[Android]TextView点击获取部分内容
TextView控件本身有很多属性可以进行控制,如果要获取内容只需要getText()方法就可以实现,同时也可以为TextView设置各种监听器。但是,如果想要实现点击获取TextView内部的部分内容,则仅仅靠TextView自带的功能实现起来就比较困难了。比如说TextView文本是一段英文,想要实现点击每个单词以获取单词内容,这该如何实现呢?
经过不懈努力,我终于在stackoverflow上找到了一种解决方法,据说是目前为止单纯使用TextView实现这一功能的最佳方法。整理如下:
首先在MainActivity中对TextView设置Spannable,设置点击单词响应方法getEachWord()并且设置TextView点击可响应。
textView.setText(text, BufferType.SPANNABLE);
//点击每个单词响应
mArticleActivity.getEachWord(textView);
textView.setMovementMethod(LinkMovementMethod.getInstance());
点击响应方法getEachWord()内容如下:
public void getEachWord(TextView textView){
Spannable spans = (Spannable)textView.getText();
Integer[] indices = getIndices(
textView.getText().toString().trim(), ' ');
int start = 0;
int end = 0;
// to cater last/only word loop will run equal to the length of indices.length
for (int i = 0; i <= indices.length; i++) {
ClickableSpan clickSpan = getClickableSpan();
// to cater last/only word
end = (i < indices.length ? indices[i] : spans.length());
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
start = end + 1;
}
//改变选中文本的高亮颜色
textView.setHighlightColor(Color.BLUE);
}
private ClickableSpan getClickableSpan(){
return new ClickableSpan() {
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
String s = tv
.getText()
.subSequence(tv.getSelectionStart(),
tv.getSelectionEnd()).toString();
Log.d("tapped on:", s);
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(false);
}
};
} public static Integer[] getIndices(String s, char c) {
int pos = s.indexOf(c, 0);
List<Integer> indices = new ArrayList<Integer>();
while (pos != -1) {
indices.add(pos);
pos = s.indexOf(c, pos + 1);
}
return (Integer[]) indices.toArray(new Integer[0]);
}
具体的实现过程是:1、将TextView内容转换为Spannable对象;2、使用getIndices方法将文本内容根据空格划分成各个单词;3、为每个单词添加ClickableSpan;4、在ClickableSpan对象实例化过程中复写onClick方法,取出被点击的部分的文本内容。
这样的实现过程有几个注意点:
1、ClickableSpan有默认的属性,可点击的超链接默认有下划线,并且是蓝色的,如果需要改变默认属性可以在复写的updateDrawState()方法中加入setColor()和setUnderlineText()方法。
2、上面提到的setColor()设定的是span超链接的文本颜色,而不是点击后的颜色,点击后的背景颜色(HighLightColor)属于TextView的属性,Android4.0以上默认是淡绿色,低版本的是黄色。改颜色可以使用textView.setHighlightColor(Color.BLUE)来实现。
3、例子中将点击获取的文本使用Log打印出来,可以发现这里的文本切割方法仅仅针对空格,所以取得的单词会有标点符号等,如果要获取严格的单词,则还需对获取的文本进一步处理。
更正:文中原来Integer[] indices = getIndices( textView.getText().toString().trim()+" ", ' ');
改为Integer[] indices = getIndices( textView.getText().toString().trim(), ' ');
原来的多出的这个空格是为多段文本而设的,如果是一段文本则不加空格,否则会报错。附上一个测试通过的实验程序,可以看看具体效果。点击下载
最新文章
- C# List 的一些操作 (两List元素是否想同,List是否包含在另一个List中)
- hdu 5720
- 信息加密之非对称加密DH算法
- C#.NET 大型通用信息化系统集成快速开发平台 4.0 版本 - 拆分表、联系方式的拆分?
- Codeforces Round #268 (Div. 2) ABCD
- Windows 10:解决开机显示C:\WINDOWS\system32\config\systemprofile\Desktop不可用的方法
- Starting zabbix_agentd: No such file or directory
- java程序员必须会的技能
- Javascript中Number()、parseIn()和parseFloat()的区别
- CSS 3的display:盒类型详解
- JavaEE SSH框架整合(三) struts2 异常、http错误状态码处理
- ESB与SOA的关系
- mfc---ActiveX控件
- Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染2创建Vue2+webpack4项目
- 内核block机制
- shell编程:基本语法
- Unix环境高级编程:fork, vfork, clone
- 深入volley(三)自己来写volley
- Python爬虫教程-03-使用 chardet 检测编码
- 【转】SWFUpload使用指南
热门文章
- C#中防止程序多次运行
- C++ Tricks(一)—— 判断字符串 string 对象的所有字符都相等
- Android中CursorLoader的使用、原理及注意事项
- 小小ARC造福无数码农
- Summary Day30
- js自动记忆用户名(可以设置cookie多存几天)
- VC6.0 MFC中WebBrowser控件禁止新窗口弹出的解决办法
- [Angular2 Form] Create custom form component using Control Value Accessor
- css聊天气泡样式
- [Webpack] Configure Prepack with Webpack