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上显示的是挂在的对象,而不是文本本身。
下面分析一下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。
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实现图文混排以及图片点击交互
点击浏览图片