Android富文本編輯器(一):基礎知識
目前主流的基於Android富文本開發方式思路如下:
- 基於TextView圖文混排
使用方式:
TextView textView = new TextView(context);
textView.setText(Html.fromHtml(“xxxxxx”));
優點:簡單、易用、學習成本低,直接輸入html即可
缺點:支持的樣式不夠靈活,有些效果實現不了。例如圖片的環繞效果
- 基於布局的實現方式:
通過實現多種布局或者模板的方式實現。
優點:簡單直接
缺點:復雜樣式或者多種樣式的情況開發效率低下,系統資源占用較多、卡頓,並且不夠靈活。
我們平常使用TextView的setText()方法傳遞String參數的時候,其實是調用的public final void setText (CharSequence text)方法:
/** * Sets the string value of the TextView. TextView <em>does not</em> accept * HTML-like formatting, which you can do with text strings in XML resource files. * To style your strings, attach android.text.style.* objects to a * {@link android.text.SpannableString SpannableString}, or see the * <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources"> * Available Resource Types</a> documentation for an example of setting * formatted text in the XML resource file. * * @attr ref android.R.styleable#TextView_text */ @android.view.RemotableViewMethod public final void setText(CharSequence text) { setText(text, mBufferType); }
而String類是CharSequence的子類,在CharSequence子類中有一個接口Spanned,即類似html的帶標記的文本,我們可以用它來在TextView中顯示html。但在上面Android源碼注釋中有提及TextView does not accept HTML-like formatting。
android.text.Html類共提供了三個方法,可以到Android幫助文檔查看。
public static Spanned fromHtml (String source) public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) public static String toHtml (Spanned text)
其中Html.ImageGetter是一個接口,我們要實現此接口,在它的getDrawable(String source)方法中返回圖片的Drawable對象
參數說明:source=需要展示的html文本內容,imageGetter=需要繼承Html.ImageGetter接口實現邏輯,tagHandler=這個參數表示,當textView解析遇到無法識別的html標簽是否發送通知或者消息,如果遇到無法解析的標簽,該方法將會被調用。這個沒有具體測試過,一般賦值null。
fromHTML的源碼
span
Spans,一個強大的概念
Span元素的繼承結構是:SpannableString -> Spannable -> Spanned -> CharSequence。后面三個都是接口,SpannableString是最終的實現類。
對應上述代碼,我們先構造的SpannableString是掛載了富文本對象的字符串,在TextView上顯示的是掛在的對象,而不是文本本身。
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。
Spannable、Spanned、Editable用法及差別
基於Android的富文本展現開發實踐--AndroidCoreText
如何實現一個 Android 端的富文本編輯器? - 知乎
【譯】Spans,一個強大的概念
為什么不用webview
webviews can be problematic if they are used in listviews
同步方案的問題:OOM
異步方案的一個問題:
Android ImageGetter images overlapping text
圖片和文字會重疊
如果是異步下載的話,一開始這里因為沒有得到圖片,所以這個圖片區域就沒有,當異步下載到圖片后,不會再調用ImageGetter 的 public Drawable getDrawable(String source) 方法,下載下來圖片如果比較大,會覆蓋住之前的文字
解決方法:
https://www.cnblogs.com/haobo/p/3158449.html
android textView 加載HTML 異步加載網絡圖片
點擊放大
TextView + Spanned實現圖文混排以及圖片點擊交互
點擊瀏覽圖片