Android 设置完autoLink属性后自定义跳转到指定界面
在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属性后自定义跳转到指定界面相关推荐
- android:autolink 颜色,Android设置完autoLink属性后自定义跳转到指定界面
在TextView 中设置autoLink 属性可以自动识别Web URL,电话号码,电子邮件地址添加下划线改变字体颜色并实现点击事件,支持自动识别的类型: android:autoLink=&quo ...
- Android之TextView设置autoLink属性后自定义跳转到指定界面
在TextView 中设置autoLink 属性可以自动识别Web URL.电话号码.电子邮件地址.添加下划线改变字体颜色并实现点击事件,支持自动识别的类型: android:autoLink=&qu ...
- Android设置drawableRight或drawableLeft后设置图标与文字间距
Android设置drawableRight或drawableLeft后设置图标与文字间距 在项目中,当给控件设置drawableRight="图片资源"或drawableLeft ...
- MobLink网页跳转app指定界面技术简介之 URL Scheme
URL Scheme是什么 由于苹果的app都是在沙盒中,相互是不能访问数据的.但是苹果还是给出了一个可以在app之间跳转的方法:URL Scheme.简单的说,URL Scheme就是一个可以让ap ...
- div+css中设置了float属性后如何让外层的高度随着内层的高度大小自动调整
overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. 一提到清除浮动,我们就会想到另外一个CSS样式 ...
- 在给Ext2 Grid设置了autoHeight属性后,如何显示滚动条
最近开发一个项目使用了Ext2 Grid的GroupingView功能,本来认为非常好用,但是发现了一个问题:在设置了autoHeight的情况下连横向滚动条都不会显示出来了.大概看了看GridVie ...
- android设置webview光标颜色,CSS自定义设置元素闪烁光标颜色
这次给大家带来CSS自定义设置元素闪烁光标颜色,CSS自定义设置元素闪烁光标颜色的注意事项有哪些,下面就是实战案例,一起来看一下. 前言因为业务需求, 要求我们的input框内的文本与悬浮的光标颜色不 ...
- android设置文本大小属性,TextView文本属性设置
在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及 ...
- Android:打开手机微博app,跳转至指定用户页面用于关注
文章内容如标题 先看一下实现效果: 跳转至微博 好了,我来说一下这个怎么实现,很简单 1,搞一个监听 Tv_microblog.setOnClickListener(new View.OnClickL ...
最新文章
- 从Varchar转换为 datetime
- 西数硬盘刷新固件_玩4k如何选硬盘?究竟那些硬盘适合你
- 关于图片延迟加载的解决方案(针对移动端)
- springboot 整合druid
- vue-resource.js的get和post的正确用法
- 关于抽象类与接口的理解
- 微信小程序引用php函数,微信小程序Page中data数据操作和函数调用详细介绍
- celery 停止_celery 停止执行中 task
- 冒泡排序及其三种优化方案
- VS2008环境下开发的某些程序在其他机器运行提示“由于应用程序配置不正确,应用程序未能启动”的问题(IIS)...
- BZOJ3157/BZOJ3516 国王奇遇记(矩阵快速幂/数学)
- Pytorch—时序数据的加载与简单处理
- pxe网络启动_什么是网络启动(PXE),以及如何使用它?
- 使用selenium爬取艺恩网年度票房(8.16)
- 穿山甲android对接错误码40029,头条 穿山甲广告 错误码列表
- 定时任务实现方式对比
- wine: /home/cpr/.wine is not owned by you
- 奇迹服务器如何修改爆率,奇迹萌新教程系列-奇迹装备是否掉落配置调整
- 如何用HTML和css实现拼图,怎样使用DIV+CSS实现拼图
- STM32 CAN总线通信学习笔记(一)