• [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(), ' ');

    原来的多出的这个空格是为多段文本而设的,如果是一段文本则不加空格,否则会报错。附上一个测试通过的实验程序,可以看看具体效果。点击下载

  • 相关阅读:
    ASP.NET刷新页面的六种方法(转)
    为什么用共有属性来封装私有变量
    ASP.NET伪静态及静态
    c#操作xml练习.
    .NET+FCKEditor使用配置_带例子下载(图)
    人生三大陷阱
    ComponentOne FlexGrid for WinForms 中文版快速入门(5)设置单元格类型(下)
    ComponentOne FlexGrid for WinForms 中文版快速入门(2)设计时支持
    ComponentOne FlexGrid for WinForms 中文版快速入门(3)单元格、行列交互
    ComponentOne FlexGrid for WinForms 中文版快速入门(6)—合并单元格
  • 原文地址:https://www.cnblogs.com/lcyty/p/3265693.html
Copyright © 2020-2023  润新知