解决设置clickablespan后长按冲突的问题
解决设置ClickableSpan后长按冲突的问题
问题描述
3月份修改别人代码的时候想要屏蔽TextView的长按事件,发现TextView有重写OnTouchEvent方法,然后在其中加了长按事件的判断,是长按事件则不做任何处理。结果测试发现并没有得到想要的效果,所以继续查看代码,最终发现,代码里对TextView设置了setSpan(new ClickableSpan),导致长按事件无法被我们捕捉到。
分析
因为查看代码是因为添加了setSpan(new ClickableSpan)方法导致长按无法被检测到,所以主要是分析ClickableSpan来寻找解决方法。
ClickableSpan
If an object of this type is attached to the text of a TextView with a movement method of LinkMovementMethod, the affected spans of text can be selected. If selected and clicked, the {@link #onClick} method will be called.
翻译一下:如果这个类型被添加到TextView的text上,并且这个TextView有一个LinkMovementMethod的行为方法,则text可以被选择。如果选择并且点击,则onClick方法会被调用。
就是说ClickanleSpan被设置到TextView的某段text上,点击被设置的text,则会调用ClickanleSpan的onClick方法。
LinkMovementModel
A movement method that traverses links in the text buffer and scrolls if necessary. Supports clicking on links with DPad Center or Enter.
翻译一下:链接文字的行为方法并在需要是滚动。支持DPad中心或输入的链接点击。
查看LInkMovementModel的源码发现,它有一个onTouchEvent方法:
@Override
public 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);
}
查看源码发现,它只是处理了ACTION_UP(抬起)与ACTION_DOWN(按下)事件,里面没有处理长按事件,也没有长按事件的接口。
所以解决方法找到了,就是重写LInkMovementModel的onTouchEvent()方法。
解决方法
写一个LinkMovementClickMethod类,继承LinkMovementMethod类,然后重写onTouchEvent()方法。
将源码中的onTouchEvent代码复制过来,加上一个判断,如果点击不是长按,则按照源码的处理方式处理,代码如下:
public class LinkMovementClickMethod extends LinkMovementMethod {
private long lastClickTime;
private static final long CLICK_DELAY = 500l;
@Override
public 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[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
============================修改的部分==============================
if (action == MotionEvent.ACTION_UP) {
if (System.currentTimeMillis() - lastClickTime < CLICK_DELAY) {
link[0].onClick(widget);
}
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
lastClickTime = System.currentTimeMillis();
}
============================修改的部分==============================
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
public static LinkMovementClickMethod getInstance() {
if (null == sInstance) {
sInstance = new LinkMovementClickMethod();
}
return sInstance;
}
private static LinkMovementClickMethod sInstance;
}
这样长按事件就被排除在外,问题得以解决。
解决设置clickablespan后长按冲突的问题的更多相关文章
- android 布局 使用 viewPager 时,如何解决 和 子页面 长按滑动 冲突问题
使用 viewPager 时,如何解决 和 子页面 长按滑动 冲突问题. 我的问题原型: 这个问题,我相信遇到的人会比较少,我是在 一个 viewPager 中,其中 一个 fragment 中实现了 ...
- Windows10用fiddler抓包Android应用(解决手机设置代理后无法上网,设置只抓app包)
1.环境准备 1.电脑上安装fiddler 2.手机和电脑在同一个局域网内 2.设置 1.fiddler>Tools>Fiddler Options>Connections 勾选Al ...
- catalina.sh设置JAVA_HOME后还无法解决更换JDK有关问题
catalina.sh设置JAVA_HOME后还无法解决更换JDK问题 表示linux已经安装默认的JDK,需要查找配置文件,更换JDK路径为指定的路径 在root用户下 使用echo $PATH 查 ...
- uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题
原文:uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题 开发中碰到一个问题,当RichEditBox输入的文本达到一定行数的时候,滚动条此时位于底部,改变文本样式(如字体 ...
- 解决Button设置disabled后无法执行后台代码问题
一.开始调式下面的程序,发现Button在js中设置disabled后无法执行后台代码(btnsave_Click)问题 <asp:Button ID="btnsave" r ...
- Android——MeasureSpec学习 - 解决ScrollView嵌套ListView和GridView冲突的方法
原文地址:http://blog.csdn.net/yuhailong626/article/details/20639217 在自定义View和ViewGroup的时候,我们经常会遇到int ...
- Loadrunner解决启动浏览器后页面显示空白
Loadrunner解决启动浏览器后页面显示空白 2018年5月20日,今天照常打开Loadrunner准备学习,在录制的时候却出现了一个问题,浏览器可以启动,但是程序页面缺是加载不出来,主要症状体现 ...
- 【转载】解决k8s中的长连接负载均衡问题
原文链接:一流铲屎官二流程序员[解决k8s中的长连接负载均衡问题] 长连接与短连接: 简介 长连接是指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测 ...
- 子div设置float后导致父div无法自动撑开的问题
子div设置float后会导致父div无法自动撑开 原因:内部的DIV因为float:left之后,就丢失了clear:both和display:block的样式,所以外部的DIV不会被撑开. 以下是 ...
随机推荐
- Flex中TitleWindow传值
Flex中TitleWindow传值 1.设计思路 (1)新建一个DataGrid,在其中最后一列加入三个按钮:新增.修改和删除: (2)点击新增按钮,可以将表格新增一行: (3)单击"修改 ...
- Openstack_后端存储平台Ceph
框架图 介绍 一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统 特点 CRUSH算法 Crush算法是ceph的两大创新之一,简单来说,ceph摒弃了传统的集中式存储元数据寻址的方案, ...
- jQuery.proxy()的用法
一:参考范文一 第一次接触jQuery.proxy()时感觉这个方法不实用,不明白它到底是个什么意思.今天来将jQuery官网上的解释进行一下翻译,顺便添加自己的理解和一些示例.proxy也可称为代理 ...
- Java虚拟机的锁优化
1 锁偏向.当现成请求一个对象锁时,如果获得锁,则该对象锁进入偏向模式,当该线程再次请求该对象的锁时,无需再做任何同步操作. 可通过在Java虚拟机中开启参数-XX:+UseBasedLock开启偏向 ...
- php+sqlServer 2008R2 PHPstudy下数据库环境搭建
简要:小主从事PHP二年,期间一直做后台;在过程中遇到一个奇葩的组合就是PHP+sqlServer应用场景,希望能够跟各位PHP大神分享和学习探索,如果有不对或者好的建议告知下:*~*! 一.下载sq ...
- [LOJ2230][BJOI2014]大融合
题面戳我 sol LCT维护子树size. 开一个数组\(sz_i\)表示一个节点的所有虚儿子的size和,\(sum_i\)表示以一个节点为根的子树的\(size\)和,可见\(sz_u=\sum_ ...
- Bzoj2134:单选错位
题面 Bzoj Sol 第\(i\)道题选对的概率就是\(\frac{min(a[i-1], a[i])}{a[i]*a[i-1]}\) # include <bits/stdc++.h> ...
- Bzoj3992:[SDOI2015]序列统计
题面 Bzoj Sol pts 1 大暴力很简单,\(f[i][j]\)表示到第\(i\)个位置,前面积的模为\(j\)的方案 然后可以获得\(10\)分的好成绩 # include <bits ...
- [AH/HNOI2017]礼物
\[推推公式,即求\Sigma^{n}_{i=1} (x_{i+k}-y_i+c)^2最小,c范围为[-m, m]\] \[拆开,就是\Sigma x_i^2 + \Sigma y_i^2 + n * ...
- 近期安卓与IOS招聘面试有感
版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.你总是想一步登天,却不知道路是一步步走出来的 大概是放年假前一个月开始招聘吧,陆陆续续到目前为止安卓面试10几个,IOS面试了15个左右,本以为 ...