教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Android培訓之SpannableString的使用

更新時間:2016年07月22日17時22分 來源:Android培訓學院 瀏覽次數(shù):

社交軟件里的SpannableString的使用
實現(xiàn)類似微博的信息流展示
 
簡介:社交軟件里常見的emoji表情、@聯(lián)系人等功能,可以在一個TextView里處理圖片顯示和文字點擊等復雜的行為,通過此文檔可以掌握該功能的實現(xiàn)方法。
 

1.基本知識

  1. SpannableString(復合字符串)類
該類的對象可被設置為TextView的正文,在顯示原有文本的基礎上,增加多種富文本特性。

  1. CharacterStyle(字符格式)的子類
在上面的setSpan方法可以看到需要一個object作為參數(shù),該參數(shù)即為CharacterStyle的子類,有文本的前景顏色、點擊、背景色、圖片、下劃線等格式可供使用。

2.可點擊文本,如 #話題#、@聯(lián)系人 的處理

  1.  先上代碼
下面的代碼使得字符串里的“只是”兩個字符可被點擊,點擊時會彈出Toast提示。
 
 

 
下面分析代碼里的幾個參數(shù)

  1. str是用于顯示的原始字符串
  2. 參數(shù)1,ClickableSpan對象
聲明被修飾的字符串可以被點擊。被點擊時會回調(diào)onClick方法,要跳轉(zhuǎn)界面還是要彈個Toast,根據(jù)業(yè)務需求變化。
  1. 參數(shù)2,start
該值表示要設置為clickspan的字符串起始位置,最小值為0.
  1. 參數(shù)3,end
該值表示要設置為clickspan的字符串終止位置,最大值為文本的length.
  1. 參數(shù)4,flags
該值用于說明,當被選中文字前后新增內(nèi)容,新的字符是否受span影響。從使用來看,只在使用EditText的時候才會產(chǎn)生影響。信息流展示只要使用SPAN_EXCLUSIVE_EXCLUSIVE 即可。

  1. 參數(shù)5,MovementMethod對象
用于分析TextView使用的所有span,在TextView發(fā)生touch事件的時候會先交由movementMethod對象判斷是否有CLickableSpan需要被處理。此參數(shù)必須設置,否則ClickableSpan的onClick方法不會被回調(diào)。
  1. 匹配#話題#或@聯(lián)系人,并提供點擊響應。
    1. 使用正則表達式確定start和end位置
從之前的代碼可以看到,設置文字點擊監(jiān)聽的代碼是固定不變的,比較費腦的是怎么確定start和end的位置。#話題#和@聯(lián)系人都是固定格式的字符串,查找固定格式的字符串應使用正則表達式來處理。上代碼:
 
 

  1. 參數(shù)1,,正則表達式的查詢規(guī)則
本文不做講解,有需要請自行搜索“正則表達式”。
  1. 參數(shù)2,參數(shù)3,Pattern和Matcher
都是JDK里用于處理正則表達式的類,使用方法是固定的,可以參見代碼注釋。
  1. TopicClickableSpan
繼承自ClickableSpan,由于ClickableSpan的onClick方法參數(shù)為View,無法區(qū)分出被點擊的span,需要在構(gòu)造方法里傳遞話題字符串以供區(qū)分不同的話題。

  1. @聯(lián)系人的點擊處理
更換正則表達式和自定義的ClickableSpan即可。

3.emoji表情的顯示處理

  1. ImageSpan
可以將文字替換為圖片顯示,接收的圖片可以是資源id也可以是Bitmap。
  1. Emoji表情
從服務器傳過來的只是字符串,但是應該具備類似[/嚇死]或者/xs這樣的特殊格式,客戶端通過正則表達式確定表情字符串的start和end位置,將文字轉(zhuǎn)換為圖片并顯示到文本框。
 
 
 

  1. EmojiList類
根據(jù)匹配到的表情名稱查找出來的對應圖片id。用于封裝所有的表情資源

4.將超鏈接轉(zhuǎn)換為圖片,并提供點擊處理

通過正則表達式匹配到URL的start和end位置,并且同時設置ImageSpan和ClickableSpan到該段字符上,使得該段字符串同時具備兩種特性
 
 
 


5.ClickSpan和ListView的item點擊事件沖突解決


5.1存在的問題
當包含ClickableSpan的TextView作為ListView的item存在時,由于點擊事件的處理沖突,會導致列表的點擊事件無法響應。目前網(wǎng)絡上的解決方案只能:“ClickableSpan響應 + item單擊/長按”響應,本文可以則可以“ClickableSpan 響應+ item單擊 + item長按 ”響應,并且不存在滑動時會長按響應的問題。
5.2處理方法分析
5.21處理焦點方法
TextView.setMovementMethod()方法會導致TextView的點擊判斷被修改,使得onTouchEvent方法始終返回為true,導致ListView無法獲取touch事件,所以需要在setMovementMethod后將焦點等標志位設為false
5.22自定義MovementMethodLinkMovementMethod的onTouchEvent方法里最終會調(diào)用到Touch.onTouchEvent,該方法將down事件返回為true(見下圖),使得TextView始終攔截Touch事件,導致ListView的item點擊無法響應。所以需要自定義LinkMovementMethod
來修改down事件的返回值,同時在TextView的onTouchEvent里根據(jù)自定義的標志位來決定是否攔截touch事件。

  1. 自定義TextView
  1. 自定義LinkMovementMethod
  1. 使用方法
使用自定義的MyTextView,Textview.setMovementMethod()改為使用TextView. setLocalLinkMovementMethod(LocalLinkMovementMethod.getInstance());
當前的解決方案保證了只在有ClickableSpan被點擊時TextView才攔截touch事件,也就使得ListView的點擊事件可以正常響應了。
更多詳情請查看帖子:
http://bbs.itheima.com/thread-276002-1-1.html
http://bbs.itheima.com/thread-276003-1-1.html
 

 本文版權歸傳智播客Android培訓學院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客Android培訓學院
首發(fā):http://oisangadgets.com/Android
0 分享到:
和我們在線交談!