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

全國(guó)咨詢/投訴熱線:400-618-4000

Android培訓(xùn)之SpannableString的使用

更新時(shí)間:2016年07月22日17時(shí)22分 來(lái)源:Android培訓(xùn)學(xué)院 瀏覽次數(shù):

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

1.基本知識(shí)

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

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

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

  1.  先上代碼
下面的代碼使得字符串里的“只是”兩個(gè)字符可被點(diǎn)擊,點(diǎn)擊時(shí)會(huì)彈出Toast提示。
 
 

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

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

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

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

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

3.emoji表情的顯示處理

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

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

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

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


5.ClickSpan和ListView的item點(diǎn)擊事件沖突解決


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

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

 本文版權(quán)歸傳智播客Android培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Android培訓(xùn)學(xué)院
首發(fā):http://metathetuscanyresort.com/Android
0 分享到:
和我們?cè)诰€交談!