之前的項目中有發布富文本帖子的需求,而受限于屏幕大小等原因,移動設備上的富文本編輯功能一直是個難題。這個系列的文章會介紹和討論當時開發過程中遇到的問題以及解決方案,希望能給大家日后的開發帶來一些幫助。
我自己開發的富文本控件也上傳到了github,點此下載:github
首先,一個富文本編輯器最基本功能需要包括:圖文混排、字體加粗等樣式、插入鏈接、插入表情等方法。如果接觸過安卓富文本編輯的相關知識,會知道安卓平臺提供了一套基于Span的富文本控件,來完成在EditText中的樣式排布。包括圖片(ImageSpan),不同的文字樣式(StyleSpan),url樣式(UrlSpan)等都有對應的類型。比如下面這段代碼就是添加了一個url鏈接在文本的start和end之間:
SpannableString spannable = new SpannableString(url);
URLSpan =new URLSpan(url);
spannable.setSpan(span,start,end,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
要理解上述這段代碼,首先介紹一下安卓中的span這個概念。在TextView和EditText中,顯示的是文本,而span是“附著”在相應文本上的對象。在繪制時,展示的是這些“附著”的對象而不是文本本身。這可以類比成一個cosplay,其實還是一段段的文本,但是不同文本戴上了不同的面具,化了不同的裝扮,展示出了不同的效果。
Span元素的繼承結構是:SpannableString -> Spannable -> Spanned -> CharSequence。后面三個都是接口,SpannableString是最終的實現類。
對應上述代碼,我們先構造的SpannableString是掛載了富文本對象的字符串,在TextView上顯示的是掛在的對象,而不是文本本身。
下面分析一下setSpan這個方法:
public void setSpan(Object what, int start, int end, int flags);
最后一個參數flags的含義是這種富文本在其之前或之后添加文本時是否需要將同樣的樣式應用于其上。
經常使用的flag有:
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)
- Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)
- Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
一般來說,ImageSpan都采取的是SPAN_EXCLUSIVE_EXCLUSIVE,而url會采用Spanned.SPAN_EXCLUSIVE_INCLUSIVE。
以上就是一個SpannableString的最基本用法,看起來還是挺簡單的。但是現實是骨感的,在現實開發中,會遇到很多的問題,后續會慢慢介紹。
最后還是歡迎大家下載我的源碼對照文章閱讀。
Android富文本編輯器(二):圖文混排以及圖片上傳處理
Android富文本編輯器(三):文字樣式
Android富文本編輯器(四):HTML文本轉換