我想做一個列表視圖有TextView元素,其中每個包含一個SpannableString。這些TextView的內容從Html標記中的ArrayList中獲取,並使用Html.fromHtml轉換爲SpannableStrings。現在,Html.fromHtml有很多性能問題。於是,我就使Html.fromHtmlHtml.fromHtml的替代軟件?
class NeoHTML extends DefaultHandler {
SpannableStringBuilder s;
String html;
Context context;
public NeoHTML(String html,Context context) {
s = new SpannableStringBuilder("");
this.html = html;
this.context=context;
getXml();
}
public SpannableStringBuilder fromHTML() {
return s;
}
public void getXml() {
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
DefaultHandler defaultHandler = new DefaultHandler() {
int boldTag = 0;
int italicsTag = 0;
int underlineTag = 0;
int pointer = 0;
boolean brpassed=false;
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("B")) {
boldTag += 1;
}
if (qName.equalsIgnoreCase("I")) {
italicsTag += 1;
}
if (qName.equalsIgnoreCase("U")) {
underlineTag += 1;
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
int tstart=start;
if(new String(ch, start, length).startsWith("[ ]")){
s.append("b");
Typeface font = Typeface.createFromAsset(context.getAssets(), "tickfont.ttf");
s.setSpan (new CustomTypefaceSpan("", font),pointer, pointer+1,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
pointer+=1;
tstart+=3;
}
else if(new String(ch, start, length).startsWith("[*]")){
s.append("a");
Typeface font = Typeface.createFromAsset(context.getAssets(), "tickfont.ttf");
s.setSpan (new CustomTypefaceSpan("", font),pointer, pointer+1,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
pointer+=1;
tstart+=3;
}
if (boldTag > 0 || italicsTag > 0 || underlineTag > 0) {
s.append(new String(ch, tstart, length));
if (boldTag > 0) {
s.setSpan(new StyleSpan(
android.graphics.Typeface.BOLD), pointer,
pointer + length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (italicsTag > 0) {
s.setSpan(new StyleSpan(
android.graphics.Typeface.ITALIC), pointer,
pointer + length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (underlineTag > 0) {
s.setSpan(new UnderlineSpan(), pointer, pointer
+ length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else {
s.append(new String(ch, tstart, length));
}
pointer += length;
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
if (qName.equalsIgnoreCase("B")) {
boldTag -= 1;
}
if (qName.equalsIgnoreCase("BR")) {
s.append("\n");
pointer+=1;
brpassed=true;
}
if (qName.equalsIgnoreCase("I")) {
italicsTag -= 1;
}
if (qName.equalsIgnoreCase("U")) {
underlineTag -= 1;
}
}
};
saxParser.parse(new InputSource(new StringReader(html)),
defaultHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
}我自己的版本
這是一個簡單的基於SAX解析器。我的靈感來自CommonsWare Is there a faster way to decode html characters to a string than Html.fromHtml()?的回答。它具有最小的功能(粗體,斜體,下劃線和中斷)但即便如此,性能並沒有得到改善。我有一些想法,比如將textview合成爲位圖並將其緩存在內存中,而不必在listview回收時再次將其重新渲染。任何人都可以提出任何想法..(請避免NDK爲基礎的解決方案,因爲我從來沒有成功編譯任何它們,它增加了不必要的複雜性)
試圖使用「低級」拉解析器? – pskink 2014-10-22 08:31:34
@pskink,我不希望它太複雜。這是一個小問題。添加NDK不是一種選擇。抱歉。 但你能建議一個好的低級解析器嗎? – avinayak 2014-10-22 08:38:51
複雜?你的意思是簡單嗎?請參閱:http://pastebin.com/6yU3tGaR – pskink 2014-10-22 09:06:29