对TextVIew中特定字符串设定onTouchEvent方法

上面是Iphone备忘录的图,笔者之前接到一个需求是实现点击文本框里的数字,弹出一个类似上图的按钮,显示出复制,要求是这个按钮的位置必须是根据你点击的位置进行定位(为什么这么说,是因为我们不可能把按钮放在你点击的地方那样显示效果不太好,一般都是在点击的位置再往上一定的尺寸)。关于这个需求,在脑海里速度分析下,就能找出几个点,首先,我们是要过滤TextView里的字符串,找出所有的数字,这个用正则很好实现,然后要给每串数字一个点击事件,这个可以通过SpannableString.setSpan和TextView.setMovementMethod(MovementMethod movement)来实现,实现起来大概是这样。
private void init() {
tvMain.setMovementMethod(LinkMovementMethod.getInstance());
SpannableString s = new SpannableString(CONTENT);
filterNumber(s);
tvMain.setText(s);
}
private static final String REG = "\\d+";
public class TextClickableSpan extends ClickableSpan {
private String text;
public TextClickableSpan(String text) {
this.text = text;
}
@Override
public void onClick(View view) {
//do something
}
}
private void filterNumber(Spannable s) {
Matcher m = Pattern.compile(REG).matcher(s.toString());
while (m.find()) {
String text = m.group();
TextClickableSpan span = new TextClickableSpan(text);
s.setSpan(span,m.start(),m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
当我想在onClick()里做处理的时候,我发现我无法得到我当前点击的位置,这让我想起来一个叫做onTouchEvent的方法,可惜ClickSpan里没这方法。于是我就自定义了一个TouchableSpan类
public abstract class TouchableSpan extends CharacterStyle implements UpdateAppearance {
@Override
public void updateDrawState(TextPaint tp) {
tp.setColor(tp.linkColor);
tp.setUnderlineText(true);
}
public abstract void onActionUp(View view,MotionEvent event);
}
有两个方法,第一个方法是我直接从ClickableSpan里抄过来的,很明显,这是用来设置样式的,分别是颜色和下划线。第二个方法是onActionUp(View view,MotionEvent event);这个事我自定义的,用来响应我们点击松手时的事件,在这里,我传入了一个MotionEvent,这样我们就能获得到点击的坐标了。但是又出现一个问题,LinkMovementMethod里只会调用ClickableSpan的onClick()方法。所以我最后又写了一个TouchableMovementMethod继承LinkMovementMethod类
public class TouchableMovementMethod extends LinkMovementMethod {
private static TouchableMovementMethod sInstance;
public static TouchableMovementMethod getInstance() {
if (sInstance == null) {
sInstance = new TouchableMovementMethod();
}
return sInstance;
}
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);
TouchableSpan [] touchSpans = buffer.getSpans(off, off, TouchableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
} else if (touchSpans.length != 0) {
if (action == MotionEvent.ACTION_UP) {
touchSpans[0].onClick(widget,event);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(touchSpans[0]),
buffer.getSpanEnd(touchSpans[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return false;
}
}
代码很简单,我只是重写了onTouchEvent方法(这个方法是LinkMovementMethod 本来就有的),我稍作了一些修改,让他既可以支持原有的ClickableSpan,又可以支持我们的TouchableSpan。这样就能很好的实现无法获得点击坐标的难题了,,
相关博文:自定义可点击的ImageSpan并在TextView中内置“View“
对TextVIew中特定字符串设定onTouchEvent方法的更多相关文章
- java中两字符串比较--compareTo方法
java.lang.String.compareTo() 方法比较两个字符串的字典,比较是基于字符串中的每个字符的Unicode值 String n1 = "1"; String ...
- JavaScript中去除字符串空格的方法
语法 string.trim() 参数值 无 返回值 类型:string 描述:返回移除头尾空格的字符串 技术细节 JavaScript版本: ECMAScript 5 去除字符串左右两端的空格,在v ...
- C# 从 UTF-8 流中读取字符串的正确方法
我们下面的代码是从一个流 stream 中读取 UTF-8 编码的字符串.我们可以先考虑一下其中存在的潜在问题. string ReadString(Stream stream) { var sb = ...
- MyEclipse如何查找指定工程下所有或指定文件中特定字符串并且可进行批量替换
查找操作步骤:(1)在myEclipse里菜单选择-Search-Search(快捷键:ctrl+h);(2)在弹出对话框中选File Search选项,然后在第一个文本框中输入“要查找的字符串”(为 ...
- python中的字符串内置方法小结
#!/usr/local/bin/python3 # -*- coding:utf-8 -*- ''' name="my wife is mahongyan" ---------- ...
- linux查看日志中特定字符串以及前后信息内容命令
在项目实施过程中,我们经常会查看日志,更是经常会根据某些特地字符串去查找日志内容. 下面就是日志查找命令: 1.查询字符串命令: cat fileName|grep '要查找的字符串' 实例:cat ...
- 在SQL中 给字符串补0方法
--第一种方法SELECT RIGHT('00000'+CAST(ID AS nvarchar(50)),5) FROM dbo.TableName --左边补0,如 00001,00039 SELE ...
- C#中判断字符串相等的方法
可以使用如下方式: 1. String.Compare(str1, str2) == 0 或者 str1.CompareTo(str2) == 0 2. str1.Equals(str2) 或者 ...
- C#替换文件中特定字符串,按照原来的编码格式保存
private void button1_Click(object sender, EventArgs e) { var txt1 = "E:\\Temp\\local"; str ...
随机推荐
- windows配置环境变量
windows配置环境变量 1.第一步 2.第二步 3.第三步
- Synchronized 与 ReentrantLock 的区别!
来源:cnblogs.com/baizhanshi/p/7211802.html 之前栈长分享了重入锁的概念:<到底什么是重入锁,拜托,一次搞清楚!>,今天现来深入了解下 Synchron ...
- 在我的Mint上安装网易云音乐
首先到网易官网下载Ubuntu版本的安装包,哪个版本多少位没多大所谓啦 然而会出现类似如下的依赖错误: dpkg: 依赖关系问题使得 netease-cloud-music 的配置工作不能继续: ne ...
- su 和 su - 命令有何不同
su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shell环境仍然是普通用户的Shell:而后者连用户和Shell环境一起切换成root身份了.只有切换了Shell环境才不会出 ...
- shell变量替换扩展 字符串计数截取
- Apache Hadoop集群离线安装部署(二)——Spark-2.1.0 on Yarn安装
Apache Hadoop集群离线安装部署(一)——Hadoop(HDFS.YARN.MR)安装:http://www.cnblogs.com/pojishou/p/6366542.html Apac ...
- 牛客练习赛48 C,D,E
C 小w的糖果 题意:3种操作,第一种是使pos右边的数全部+1,第二种是pos右边的数依次+k(k从1开始递增),第三种是pos右边的数依次+k^2(k从1开始递增). 解法:第一种我们很容易想到差 ...
- string参考
#include <iostream> #include <string.h> class string { private: char *data; public: stri ...
- 在虚拟机中使用maven编译signal server项目记录
前言 安装好 mvn Ubuntu 16.04 JDK 我是从 oracle jdk 11 lts download 网站,复制jdk-11.0.4_linux-x64_bin.tar.gz的链接 w ...
- Map集合类(一.hashMap源码解析jdk1.8)
java集合笔记一 java集合笔记二 java集合笔记三 jdk 8 之前,其内部是由数组+链表来实现的,而 jdk 8 对于链表长度超过 8 的链表将转储为红黑树 1.属性 //节点数组,第一次使 ...