在TextView 中设置autoLink 属性可以自动识别Web URL,电话号码,电子邮件地址添加下划线改变字体颜色并实现点击事件,支持自动识别的类型:

android:autoLink=“web” 匹配Web URL。

android:autoLink=“phone” 匹配电话号码

android:autoLink=“email” 匹配电子邮件地址

android:autoLink=“map” 匹配地理位置

android:autoLink=“all” 匹配所有可用的模式

android:autoLink=“none” 不匹配任何类型

也可以类似这样的设置 android:autoLink=“web|phone” 表示匹配web URL 和手机号

上面的属性也可以通过java 代码的形式对TextView 设置

setAutoLinkMask(int mask) 进行设置

设置的参数分别是:

Linkify.WEB_URLS 匹配Web UR

Linkify.PHONE_NUMBERS 匹配电话号码

Linkify.EMAIL_ADDRESSES 匹配电子邮件地址

Linkify.MAP_ADDRESSES 地理位置匹配

Linkify.ALL 匹配所有可用的模式

设置完antoLink属性,点击TextView中的链接时会跳转的对应的界面,比如点击网页的链接会跳转到系统的默认的浏览器界面,点击手机号会进入拨打电话界面,但是这都是系统默认的,我们可不可以进行拦截处理,跳转到我们指定的界面呢,当然是可以的。下面是我的拦截处理的方法。

继承 MovementMethod ,这里我们先看一下MovementMethod的源码,它的源码比较少

public class LinkMovementMethod extends ScrollingMovementMethod {private static final int CLICK = 1;private static final int UP = 2;private static final int DOWN = 3;@Overridepublic boolean canSelectArbitrarily() {return true;}@Overrideprotected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,int movementMetaState, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_DPAD_CENTER:case KeyEvent.KEYCODE_ENTER:if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {if (event.getAction() == KeyEvent.ACTION_DOWN &&event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {return true;}}break;}return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);}@Overrideprotected boolean up(TextView widget, Spannable buffer) {if (action(UP, widget, buffer)) {return true;}return super.up(widget, buffer);}@Overrideprotected boolean down(TextView widget, Spannable buffer) {if (action(DOWN, widget, buffer)) {return true;}return super.down(widget, buffer);}@Overrideprotected boolean left(TextView widget, Spannable buffer) {if (action(UP, widget, buffer)) {return true;}return super.left(widget, buffer);}@Overrideprotected boolean right(TextView widget, Spannable buffer) {if (action(DOWN, widget, buffer)) {return true;}return super.right(widget, buffer);}private boolean action(int what, TextView widget, Spannable buffer) {Layout layout = widget.getLayout();int padding = widget.getTotalPaddingTop() +widget.getTotalPaddingBottom();int areaTop = widget.getScrollY();int areaBot = areaTop + widget.getHeight() - padding;int lineTop = layout.getLineForVertical(areaTop);int lineBot = layout.getLineForVertical(areaBot);int first = layout.getLineStart(lineTop);int last = layout.getLineEnd(lineBot);ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);int a = Selection.getSelectionStart(buffer);int b = Selection.getSelectionEnd(buffer);int selStart = Math.min(a, b);int selEnd = Math.max(a, b);if (selStart < 0) {if (buffer.getSpanStart(FROM_BELOW) >= 0) {selStart = selEnd = buffer.length();}}if (selStart > last)selStart = selEnd = Integer.MAX_VALUE;if (selEnd < first)selStart = selEnd = -1;switch (what) {case CLICK:if (selStart == selEnd) {return false;}ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);if (link.length != 1)return false;link[0].onClick(widget);break;case UP:int bestStart, bestEnd;bestStart = -1;bestEnd = -1;for (int i = 0; i < candidates.length; i++) {int end = buffer.getSpanEnd(candidates[i]);if (end < selEnd || selStart == selEnd) {if (end > bestEnd) {bestStart = buffer.getSpanStart(candidates[i]);bestEnd = end;}}}if (bestStart >= 0) {Selection.setSelection(buffer, bestEnd, bestStart);return true;}break;case DOWN:bestStart = Integer.MAX_VALUE;bestEnd = Integer.MAX_VALUE;for (int i = 0; i < candidates.length; i++) {int start = buffer.getSpanStart(candidates[i]);if (start > selStart || selStart == selEnd) {if (start < bestStart) {bestStart = start;bestEnd = buffer.getSpanEnd(candidates[i]);}}}if (bestEnd < Integer.MAX_VALUE) {Selection.setSelection(buffer, bestStart, bestEnd);return true;}break;}return false;}@Overridepublic boolean onTouchEvent(TextView widget, Spannable buffer,MotionEvent event) {int action = event.getAction();if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {int x = (int) event.getX();int y = (int) event.getY();x -= widget.getTotalPaddingLeft();y -= widget.getTotalPaddingTop();x += widget.getScrollX();y += widget.getScrollY();Layout layout = widget.getLayout();int line = layout.getLineForVertical(y);int off = layout.getOffsetForHorizontal(line, x);ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);if (links.length != 0) {if (action == MotionEvent.ACTION_UP) {links[0].onClick(widget);} else if (action == MotionEvent.ACTION_DOWN) {Selection.setSelection(buffer,buffer.getSpanStart(links[0]),buffer.getSpanEnd(links[0]));}return true;} else {Selection.removeSelection(buffer);}}return super.onTouchEvent(widget, buffer, event);}@Overridepublic void initialize(TextView widget, Spannable text) {Selection.removeSelection(text);text.removeSpan(FROM_BELOW);}@Overridepublic void onTakeFocus(TextView view, Spannable text, int dir) {Selection.removeSelection(text);if ((dir & View.FOCUS_BACKWARD) != 0) {text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);} else {text.removeSpan(FROM_BELOW);}}public static MovementMethod getInstance() {if (sInstance == null)sInstance = new LinkMovementMethod();return sInstance;}private static LinkMovementMethod sInstance;private static Object FROM_BELOW = new NoCopySpan.Concrete();
}

在上面的这段代码中处理界面跳转的只有这一行 links[0].onClick(widget);我们要实现自己的跳转只要在自定义的LinkMovementMethod的这一行进行处理就行了。
先定义一个替换links[0].onClick(widget);的接口

public interface LinkClickListener {/*** true  表示要自己处理  false 使用系统默认** @param mURL* @return*/boolean onLinkClick(String mURL);
}

定义一个LinkMovementMethod的子类 LinkMovementMethodEx,在onTouchEvent方法中做了判断,在我们应用自己处理的情况,就不在走系统的默认处理,只有我们自己不处理的情况下才走系统的。

public class LinkMovementMethodEx extends LinkMovementMethod {private LinkClickListener listener;public LinkMovementMethodEx(LinkClickListener listener) {this.listener = listener;}@Overridepublic boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {int action = event.getAction();if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {int x = (int) event.getX();int y = (int) event.getY();x -= widget.getTotalPaddingLeft();y -= widget.getTotalPaddingTop();x += widget.getScrollX();y += widget.getScrollY();Layout layout = widget.getLayout();int line = layout.getLineForVertical(y);int off = layout.getOffsetForHorizontal(line, x);ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);if (links.length != 0) {if (action == MotionEvent.ACTION_UP) {if (links[0] instanceof URLSpan) {URLSpan url = (URLSpan) links[0];if (listener != null && listener.onLinkClick(url.getURL())) {return true;} else {links[0].onClick(widget);}}} else if (action == MotionEvent.ACTION_DOWN) {Selection.setSelection(buffer,buffer.getSpanStart(links[0]),buffer.getSpanEnd(links[0]));}return true;} else {Selection.removeSelection(buffer);}}return super.onTouchEvent(widget, buffer, event);}
}

在项目中的引用

public class MainActivity extends Activity {private String TAG = MainActivity.class.getSimpleName();private TextView title;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);title = findViewById(R.id.tv_content);title.setText(" 10086 中国移动的 这是百度的 https://www.baidu.com/");title.setMovementMethod(new LinkMovementMethodEx(new LinkClickListener() {@Overridepublic boolean onLinkClick(String mURL) {//在这里执行直接的处理逻辑并将返回值设置为trueLog.i(TAG, "onLinkClick: " + mURL);return false;}}));}
}

源码地址 https://github.com/songdaren123/TextLink

Android 设置完autoLink属性后自定义跳转到指定界面相关推荐

  1. android:autolink 颜色,Android设置完autoLink属性后自定义跳转到指定界面

    在TextView 中设置autoLink 属性可以自动识别Web URL,电话号码,电子邮件地址添加下划线改变字体颜色并实现点击事件,支持自动识别的类型: android:autoLink=&quo ...

  2. Android之TextView设置autoLink属性后自定义跳转到指定界面

    在TextView 中设置autoLink 属性可以自动识别Web URL.电话号码.电子邮件地址.添加下划线改变字体颜色并实现点击事件,支持自动识别的类型: android:autoLink=&qu ...

  3. Android设置drawableRight或drawableLeft后设置图标与文字间距

    Android设置drawableRight或drawableLeft后设置图标与文字间距 在项目中,当给控件设置drawableRight="图片资源"或drawableLeft ...

  4. MobLink网页跳转app指定界面技术简介之 URL Scheme

    URL Scheme是什么 由于苹果的app都是在沙盒中,相互是不能访问数据的.但是苹果还是给出了一个可以在app之间跳转的方法:URL Scheme.简单的说,URL Scheme就是一个可以让ap ...

  5. div+css中设置了float属性后如何让外层的高度随着内层的高度大小自动调整

    overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. 一提到清除浮动,我们就会想到另外一个CSS样式 ...

  6. 在给Ext2 Grid设置了autoHeight属性后,如何显示滚动条

    最近开发一个项目使用了Ext2 Grid的GroupingView功能,本来认为非常好用,但是发现了一个问题:在设置了autoHeight的情况下连横向滚动条都不会显示出来了.大概看了看GridVie ...

  7. android设置webview光标颜色,CSS自定义设置元素闪烁光标颜色

    这次给大家带来CSS自定义设置元素闪烁光标颜色,CSS自定义设置元素闪烁光标颜色的注意事项有哪些,下面就是实战案例,一起来看一下. 前言因为业务需求, 要求我们的input框内的文本与悬浮的光标颜色不 ...

  8. android设置文本大小属性,TextView文本属性设置

    在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及 ...

  9. Android:打开手机微博app,跳转至指定用户页面用于关注

    文章内容如标题 先看一下实现效果: 跳转至微博 好了,我来说一下这个怎么实现,很简单 1,搞一个监听 Tv_microblog.setOnClickListener(new View.OnClickL ...

最新文章

  1. 从Varchar转换为 datetime
  2. 西数硬盘刷新固件_玩4k如何选硬盘?究竟那些硬盘适合你
  3. 关于图片延迟加载的解决方案(针对移动端)
  4. springboot 整合druid
  5. vue-resource.js的get和post的正确用法
  6. 关于抽象类与接口的理解
  7. 微信小程序引用php函数,微信小程序Page中data数据操作和函数调用详细介绍
  8. celery 停止_celery 停止执行中 task
  9. 冒泡排序及其三种优化方案
  10. VS2008环境下开发的某些程序在其他机器运行提示“由于应用程序配置不正确,应用程序未能启动”的问题(IIS)...
  11. BZOJ3157/BZOJ3516 国王奇遇记(矩阵快速幂/数学)
  12. Pytorch—时序数据的加载与简单处理
  13. pxe网络启动_什么是网络启动(PXE),以及如何使用它?
  14. 使用selenium爬取艺恩网年度票房(8.16)
  15. 穿山甲android对接错误码40029,头条 穿山甲广告 错误码列表
  16. 定时任务实现方式对比
  17. wine: /home/cpr/.wine is not owned by you
  18. 奇迹服务器如何修改爆率,奇迹萌新教程系列-奇迹装备是否掉落配置调整
  19. 如何用HTML和css实现拼图,怎样使用DIV+CSS实现拼图
  20. STM32 CAN总线通信学习笔记(一)

热门文章

  1. 业务流程图怎么画?简单快速的方法教给你
  2. 高可用文本处理-(sed,awk)
  3. np.arctan2(x,y)解读
  4. 论文阅读3:Smart Greybox Fuzzing 智能灰盒模糊测试
  5. Smart Greybox Fuzzing
  6. IsPrime 问题
  7. 共识算法2--股权权益机制证明简介及算法实现
  8. Linux-系统管理12-进程和计划任务管理
  9. 关于apache的日志配置和模板格式分析
  10. 论文翻译与理解:Hard Positive Generation via Adversary for Object Detection