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

原來的多出的這個空格是為多段文本而設的,如果是一段文本則不加空格,否則會報錯。附上一個測試通過的實驗程序,可以看看具體效果。點擊下載

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM