Android TextView 富文本之 android.text.style.xxxSpan

前言

最近一直在作 TextView 富文本處理的工做,接觸到了比較纖細的粗字體顏色內聯圖片處理 ellipsizeLinkMovementMethod 的坑ClickableSpan 的點擊事件等問題,通過查資料看源碼作實驗三連以後,對 Android TextView 的富文本處理有了小小的體會,寫篇博客總結下本身的收穫,往後在遇到相似問題也方便回顧。android

android.text.style

富文本相關的 xxxSpan 基本都在這個包下面啦,android-28 裏的有 42 個文件,包含了各式各樣設置字體自定義繪製點擊事件段落樣式的 Span。canvas

一、CharacterStyle(來來來,你來挑畫筆)

多數 Span 的基類,有一個抽象方法:
public abstract void updateDrawState(TextPaint tp);
TextPaint 繼承自 Paint,這就給了咱們一個機會去操縱畫筆,設置前景色背景色字體顏色字體粗細字體大小等等等等,想怎麼設置怎麼設置。bash

設計:這裏的用戶名要單獨加粗
我:好,加粗
設計:不行,這樣太粗了,要那種比較纖細的粗
我:我 。。。
複製代碼

Paint.setFakeBoldText就適用於這種狀況,這個方法其實就是把畫筆變粗了而已,而不是使用粗體的字體,要更精細地控制畫筆粗細能夠用Paint.setStrokeWidth
附上解決問題連接: 如何實現 「中間這幾個字要加粗,可是不要太粗,比較纖細的那種粗」 ?佈局

二、UpdateAppearance

這個接口是空的,只是用來標識的,表示 Span 會改變字體的外貌(顏色、形狀等), UpdateLayout 稍後說,其餘的 Span 都實現 CharacterStyleupdateDrawState 方法,並對畫筆進行設置,達到變換字體外觀的目的。

三、ClickableSpan

增長了一個抽象方法public abstract void onClick(@NonNull View widget);,用於響應點擊事件(須要外部配合,如 LinkMovementMethodOnTouchListener)。
URLSpan 繼承自它,存儲一個 URL,點擊時用 startActivity 打開。post

四、UpdateLayout

UpdateAppearance 同樣是一個標識,從名字就能看出來,它還改變佈局(位置、大小等), 惟一的繼承類 MetricAffectingSpan有一個抽象方法 public abstract void updateMeasureState(@NonNull TextPaint textPaint);,用於改變字體的大小等屬性。

五、ReplacementSpan (畫布給你,你行你來畫)

以前的 Span 咱們只能設置 Paint,能作的事情頗有限, ReplacementSpanMetricAffectingSpan更進一步,直接本身接管了繪製的任務,它有兩個抽象方法 public abstract int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm);public abstract void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint);分別用於肯定繪製範圍和繪製內容。這就使得 ReplacementSpan有很大的靈活性,想畫啥就畫啥,常常用於畫內聯的圖片之類的東西。

六、其餘的 Span

ParagraphStyle相關的也有不少 Span,主要用於段落樣式的處理,我也沒用過,就不瞎說了 字體

還有 TtsSpanSuggestionSpanEasyEditSpanSpellCheckSpanSuggestionRangeSpan 。。。

最後

Android 提供了這麼多 Span,我平時用的比較多的也就ReplacementSpanClickableSpanReplacementSpan用於現實自定義的 emoji 表情和內聯的一些小圖標之類的,ClickableSpan則用於自定義點擊事件,好比在點擊@Somebody#話題#查看圖片等操做時,用本地的頁面打開。這兩個 Span 用的比較多,坑也比較多,接下來會專門對這兩個 Span 作個稍微詳細的總結。
Html.fromHtml實現的富文本處理其實也是利用 Android 提供的 Span 實現,只不過 TextView 支持的標籤十分有限,作一些簡單的處理還行,畢竟 TextView 主要顯示文本嘛,幹嗎整那麼複雜。我平時用的時候也主要是用超連接,而後經過自定義的ClickableSpanRoute打開本地頁面。spa

相關文章
相關標籤/搜索