android富⽂本显⽰⽅案格式,富⽂本处理TextView显⽰富⽂本
的三种⽅案
TextView显⽰富⽂本的三种⽅案
背景
在做Android开发的时候,⼤家可能会经常遇到这种需求:⼀个textview控件上想展⽰⼀段声明,声明的⼤部分内容是正常的很⾊字体,书名号引⽤的各种⽂件条款,使⽤蓝⾊字体显⽰,类似如下效果图。
这类需求⼀般有三种实现⽅式
⽅式⼀:使⽤多个TextView来显⽰
这是最为简单⽆脑的⽅法,但是很试⽤场景⽐较有限,当涉及到⽂字换⾏时,这种实现⽅式不⽅便处理了,这⾥就不给⼤家详细演⽰了。
⽅式⼆:SpannableString
⽅式三:使⽤Html.fromHtml
⽅式三是今天主要讲解的⼀个⽅案,将要展⽰的⽂案写成html的格式,通过内置的Html类,使⽤fromHtml⽅法将html⽂本转换为可显⽰在textview的带有各种标记的⽂字。
原理:html是xml语⾔,fromHtml⽅法中,使⽤sax⽅式对html的xml进⾏解析,在解析到能识别的标签时,根据不同的Spanned策略来标记⽂案
简单的实现⽅式如下:
String content = "⼀段html风格的字符串";
textView.setText(Html.fromHtml(content, null, null));
监听⾃定义标签
** 原理**:当html.fromHtml⽅法在处理html⽂件时,如果开发者传递了⾃定义的TagHandler,在解析的过程中,会返回不能识别的标签到TagHandler的handleTag⽅法中,开发者在这个回调中,可以⾃定义处理,该接⼝的原⽣定义如下。
public static Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler)
/**
* Is notified when HTML tags are encountered that the parser does
* not know how to interpret.
*/
public static interface TagHandler {
/**
* This method will be called whenn the HTML parser encounters
* a tag that it does not know how to interpret.
*/
public void handleTag(boolean opening, String tag,
Editable output, XMLReader xmlReader);
}
监听已有标签的⾃定义属性
原理:在监听⾃定义标签的基础上,在解析html⽂件时,会先返回不能解析的html标签,这样,开发者在这个回调中,可以在很早的时机拿到XmlReader,XmlReader是负责解析整个html⽂件的,其内部有⼀个ContentHandler,⽤于监听整个解析过程,我们可以将xmlReader中的原始进⾏保存,在需要特殊处理的时候做拦截,这样,变达到了监听已有标签的⾃定义属性的能⼒
具体代码⽰例如下:
public class HtmlTagHandler implements Html.TagHandler {
private static final String TAG = "HtmlTagHandler";
private volatile ContentHandler mOriginalContentHandler; //原始的
//监听html解析信息,接⼿后续处理
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
VLog.d(TAG, "opening: " + opening + " tag: " + tag);
//获取对xmlReader解析的控制权
if (mOriginalContentHandler == null) {
mOriginalContentHandler = ContentHandler();
xmlReader.setContentHandler(new HtmlContentHandlerWrapper(mOriginalContentHandler));//获取控制权,让HtmlContentHandlerWrapper监听解析流程
}
}
}
public class HtmlContentHandlerWrapper implements ContentHandler {
private static final String TAG = "HtmlContentHandlerWrapper";
private volatile ContentHandler mOriginalContentHandler; //原始的
private static final String ORGINAL_URI = "⾃定义的属性"; //标签内部原始字段
private static final String A_TAG = "a"; //需要特殊处理的标签
public HtmlContentHandlerWrapper(ContentHandler handler) {
mOriginalContentHandler = handler;
}
/
**
* 举例:拦截a标签,识别⾃定义字段
* @param uri
* @param localName
* @param qName
* @param atts
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if (canHandleTag(localName)) { //拦截,判断是否可以解析该标签
VLog.d(TAG, "startElement custom");
AttributesImpl a = (AttributesImpl) atts;
String orignValue = a.getValue("", ORGINAL_URI);
if (!TextUtils.isEmpty(orignValue)) { //存在⾃定义的属性时做该操作
//⾃定义的处理
}
}
}
//原流程处理
this.mOriginalContentHandler.startElement(uri, localName, qName, atts);
}
private boolean canHandleTag(String tagName) {
return A_TAG.equalsIgnoreCase(tagName);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
dElement(uri, localName, qName);
}
@Override
public void setDocumentLocator(Locator locator) {
mOriginalContentHandler.setDocumentLocator(locator);
}
@Override
textstyle
public void startDocument() throws SAXException {
mOriginalContentHandler.startDocument();
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException { mOriginalContentHandler.startPrefixMapping(prefix, uri);
}
@Override
public void endPrefixMapping(String prefix) throws SAXException { dPrefixMapping(prefix);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException { mOriginalContentHandler.characters(ch, start, length);
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { mOriginalContentHandler.ignorableWhitespace(ch, start, length);
}
@Override
public void processingInstruction(String target, String data) throws SAXException { mOriginalContentHandler.processingInstruction(target, data);
}
@Override
public void skippedEntity(String name) throws SAXException { mOriginalContentHandler.skippedEntity(name);
}
}
相关知识xml⽂档解析的三种⽅案
SAX**:(Simple API for XML****)**这种解析⽅式基于事件的模型。通俗的讲就是XML⽂件在加载的过程中,加载到不同节点会相应触发不同⽅法来处理。它属于⼀次加载。它可以处理任意⼤⼩的XML⽂件,它对内存的要求⾮常低,因为SAX采⽤的是读取⽂件的⽅式,也就是当它是⽂本⽂件在读,读完就完了,什么信息都没有保存。当然它也有其缺点,解析过程中⽆法中断,只能读取XML⽂件⽽不能修改,编码上也相对复杂与难于理解。
DOM**:(Document Object Model****)**⽂档对象模型,它是基于对象的,⼜或者基于树的。它属于两次加载,⾸先把⽂档载⼊内存,第⼆次把⽂档解析形成⼀棵树。如果⽂档过⼤对内存占⽤是很⼤的。但它也有其优点,它可以解析的过程中修改⽂件树,可以随便存储⽂件树的任意部分,相对容易理解。
**Pull****解析:**android中内置了pull解析包。这也是android程序中所推荐的xml解析⽅式。从它的字⾯上就可以看出来,其优点,pull,拉的意思。我要什么资源我就拿什么资源。我只需要xml⽂件中⼀部分,我就拉⼀部分。从⽽节省资源,提⾼效率。当然在J2EE中也可以使⽤Pull解析。Pull解析也⾮常易于理解。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论