android中实现文字的超链接的应用内跳转
2016-07-07 17:40
501 查看
实现像新浪微博那样的文字中有蓝色超链接,点击后跳转到应用里面的指定页面。
首先自定义一个touchListerner:
/**
* Created by App-Dev on 2015/10/20.
* 识别超链接的touchListener
*/
public class FindUrlTouchListener implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean ret = false;
TextView textView = (TextView) v;
CharSequence text = textView.getText();
Spannable sText = Spannable.Factory.getInstance().newSpannable(text);
int action = event.getAction();
//超链接的识别
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();
x += textView.getScrollX();
y += textView.getScrollY();
Layout layout = textView.getLayout();
if (layout != null) {
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = sText.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
//添加按压后的背景颜色
if (action == MotionEvent.ACTION_DOWN) {
Spanned sp = (Spanned) text;
int st = sp.getSpanStart(link[0]);
int en = sp.getSpanEnd(link[0]);
sText.setSpan(new BackgroundColorSpan(v.getResources().getColor(R.color.linkBg)), st, en, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sText);
}
if (action == MotionEvent.ACTION_UP) {
//清除按压后的背景颜色
BackgroundColorSpan[] bcs = sText.getSpans(off, off, BackgroundColorSpan.class);
if (bcs.length != 0) {
sText.removeSpan(bcs[0]);
textView.setText(sText);
}
//处理超链接
URLSpan[] urls = sText.getSpans(off, off, URLSpan.class);
//获取超链接网址
String url = urls[0].getURL();
if ((url.contains("匹配条件")) {
/**
* 通过url打开对应的应用页面
*/
} else {
//超链接为空
if (!TextUtils.isEmpty(url)) {
try {
link[0].onClick(v);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ret = true;
}
}
}
//清除按压后的背景颜色
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
BackgroundColorSpan[] bcs = sText.getSpans(0, text.length(), BackgroundColorSpan.class);
if (bcs.length != 0) {
sText.removeSpan(bcs[0]);
textView.setText(sText);
}
}
return ret;
}
}
然后textView设置OnTouchListener:
textView.setOnTouchListener(new FindUrlTouchListener());
最后只需要将包含超链接的文本设置到textView中(注意使用:Html.from(str);):
textView.setText(Html.from(str));
默认情况下textView中的超链接会有下划线。通过下面的方法可以去除:
//去掉链接的下划线
private static void setHtmlStyle(TextView textView) {
Spannable s = new Spannable.Factory().newSpannable(textView.getText());
URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = s.getSpanStart(span);
int end = s.getSpanEnd(span);
s.removeSpan(span);
span = new URLSpanNoUnderline(span.getURL());
s.setSpan(span, start, end, 0);
}
textView.setText(s);
}
private static class URLSpanNoUnderline extends URLSpan {
public URLSpanNoUnderline(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
super.onClick(widget);
}
}
首先自定义一个touchListerner:
/**
* Created by App-Dev on 2015/10/20.
* 识别超链接的touchListener
*/
public class FindUrlTouchListener implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean ret = false;
TextView textView = (TextView) v;
CharSequence text = textView.getText();
Spannable sText = Spannable.Factory.getInstance().newSpannable(text);
int action = event.getAction();
//超链接的识别
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();
x += textView.getScrollX();
y += textView.getScrollY();
Layout layout = textView.getLayout();
if (layout != null) {
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = sText.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
//添加按压后的背景颜色
if (action == MotionEvent.ACTION_DOWN) {
Spanned sp = (Spanned) text;
int st = sp.getSpanStart(link[0]);
int en = sp.getSpanEnd(link[0]);
sText.setSpan(new BackgroundColorSpan(v.getResources().getColor(R.color.linkBg)), st, en, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sText);
}
if (action == MotionEvent.ACTION_UP) {
//清除按压后的背景颜色
BackgroundColorSpan[] bcs = sText.getSpans(off, off, BackgroundColorSpan.class);
if (bcs.length != 0) {
sText.removeSpan(bcs[0]);
textView.setText(sText);
}
//处理超链接
URLSpan[] urls = sText.getSpans(off, off, URLSpan.class);
//获取超链接网址
String url = urls[0].getURL();
if ((url.contains("匹配条件")) {
/**
* 通过url打开对应的应用页面
*/
} else {
//超链接为空
if (!TextUtils.isEmpty(url)) {
try {
link[0].onClick(v);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ret = true;
}
}
}
//清除按压后的背景颜色
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
BackgroundColorSpan[] bcs = sText.getSpans(0, text.length(), BackgroundColorSpan.class);
if (bcs.length != 0) {
sText.removeSpan(bcs[0]);
textView.setText(sText);
}
}
return ret;
}
}
然后textView设置OnTouchListener:
textView.setOnTouchListener(new FindUrlTouchListener());
最后只需要将包含超链接的文本设置到textView中(注意使用:Html.from(str);):
textView.setText(Html.from(str));
默认情况下textView中的超链接会有下划线。通过下面的方法可以去除:
//去掉链接的下划线
private static void setHtmlStyle(TextView textView) {
Spannable s = new Spannable.Factory().newSpannable(textView.getText());
URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = s.getSpanStart(span);
int end = s.getSpanEnd(span);
s.removeSpan(span);
span = new URLSpanNoUnderline(span.getURL());
s.setSpan(span, start, end, 0);
}
textView.setText(s);
}
private static class URLSpanNoUnderline extends URLSpan {
public URLSpanNoUnderline(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
super.onClick(widget);
}
}
相关文章推荐
- Android开发之动画效果浅析
- Android控件--ClearEditText带清除功能的输入框
- Android来电监听和去电监听
- 如何实现android和服务器长连接呢?推送消息的原理
- Jenkins实现Android项目CI和二维码下载
- Android 控制台异常:ScrollView can host only one direct child
- Android Binder设计与实现 - 设计篇
- android--email发送邮件,文本还有附件形式的邮件
- Context.getExternalFilesDir()和Context.getExternalCacheDir()
- Android SearchView使用
- Android Studio 插件
- 热修复 nuwa android studio cmd $ANDROID_HOME is not defined
- Android Studio常用快捷键
- Android 优化性能之 如何避免--过度绘制
- android中的url跳转
- Android之Activity启动模式
- Android SeekBar使用
- android 全局dialog的实现
- android中的坐标
- Android性能优化课程:过度绘制