展会信息港展会大全

Android中为TextView增加自定义的HTML标签
来源:互联网   发布日期:2015-11-15 10:14:37   浏览:2178次  

导读:Android中的TextView,本身就支持部分的Html格式标签。这其中包括常用的字体大小颜色设置,文本链接等。使用起来也比较方便,只需要使用Html类转换一下即可。比如:textView.setText(Html.fromHtml(str));然而,......

Android中的TextView,本身就支持部分的Html格式标签。这其中包括常用的字体大小颜色设置,文本链接等。使用起来也比较方便,只需要使用Html类转换一下即可。比如:

textView.setText(Html.fromHtml(str));

然而,有一种场合,默认支持的标签可能不够用。比如,我们需要在textView中点击某种链接,返回到应用中的某个界面,而不仅仅是网络连接,如何实现?

经过几个小时对android中的Html类源代码的研究,找到了解决办法,并且测试通过。

先看Html类的源代码中有这样一段:

/**

* 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的tag进行解析部分的代码:

private void handleStartTag(String tag, Attributes attributes) {

if (tag.equalsIgnoreCase("br")) {

// We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>

// so we can safely emite the linebreaks when we handle the close tag.

} else if (tag.equalsIgnoreCase("p")) {

handleP(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("div")) {

handleP(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("em")) {

start(mSpannableStringBuilder, new Bold());

} else if (tag.equalsIgnoreCase("b")) {

start(mSpannableStringBuilder, new Bold());

} else if (tag.equalsIgnoreCase("strong")) {

start(mSpannableStringBuilder, new Italic());

} else if (tag.equalsIgnoreCase("cite")) {

start(mSpannableStringBuilder, new Italic());

} else if (tag.equalsIgnoreCase("dfn")) {

start(mSpannableStringBuilder, new Italic());

} else if (tag.equalsIgnoreCase("i")) {

start(mSpannableStringBuilder, new Italic());

} else if (tag.equalsIgnoreCase("big")) {

start(mSpannableStringBuilder, new Big());

} else if (tag.equalsIgnoreCase("small")) {

start(mSpannableStringBuilder, new Small());

} else if (tag.equalsIgnoreCase("font")) {

startFont(mSpannableStringBuilder, attributes);

} else if (tag.equalsIgnoreCase("blockquote")) {

handleP(mSpannableStringBuilder);

start(mSpannableStringBuilder, new Blockquote());

} else if (tag.equalsIgnoreCase("tt")) {

start(mSpannableStringBuilder, new Monospace());

} else if (tag.equalsIgnoreCase("a")) {

startA(mSpannableStringBuilder, attributes);

} else if (tag.equalsIgnoreCase("u")) {

start(mSpannableStringBuilder, new Underline());

} else if (tag.equalsIgnoreCase("sup")) {

start(mSpannableStringBuilder, new Super());

} else if (tag.equalsIgnoreCase("sub")) {

start(mSpannableStringBuilder, new Sub());

} else if (tag.length() == 2 &&

Character.toLowerCase(tag.charAt(0)) == 'h' &&

tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {

handleP(mSpannableStringBuilder);

start(mSpannableStringBuilder, new Header(tag.charAt(1) - '1'));

} else if (tag.equalsIgnoreCase("img")) {

startImg(mSpannableStringBuilder, attributes, mImageGetter);

} else if (mTagHandler != null) {

mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);

}

}

private void handleEndTag(String tag) {

if (tag.equalsIgnoreCase("br")) {

handleBr(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("p")) {

handleP(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("div")) {

handleP(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("em")) {

end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD));

} else if (tag.equalsIgnoreCase("b")) {

end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD));

} else if (tag.equalsIgnoreCase("strong")) {

end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));

} else if (tag.equalsIgnoreCase("cite")) {

end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));

} else if (tag.equalsIgnoreCase("dfn")) {

end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));

} else if (tag.equalsIgnoreCase("i")) {

end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));

} else if (tag.equalsIgnoreCase("big")) {

end(mSpannableStringBuilder, Big.class, new RelativeSizeSpan(1.25f));

} else if (tag.equalsIgnoreCase("small")) {

end(mSpannableStringBuilder, Small.class, new RelativeSizeSpan(0.8f));

} else if (tag.equalsIgnoreCase("font")) {

endFont(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("blockquote")) {

handleP(mSpannableStringBuilder);

end(mSpannableStringBuilder, Blockquote.class, new QuoteSpan());

} else if (tag.equalsIgnoreCase("tt")) {

end(mSpannableStringBuilder, Monospace.class,

new TypefaceSpan("monospace"));

} else if (tag.equalsIgnoreCase("a")) {

endA(mSpannableStringBuilder);

} else if (tag.equalsIgnoreCase("u")) {

end(mSpannableStringBuilder, Underline.class, new UnderlineSpan());

} else if (tag.equalsIgnoreCase("sup")) {

end(mSpannableStringBuilder, Super.class, new SuperscriptSpan());

} else if (tag.equalsIgnoreCase("sub")) {

end(mSpannableStringBuilder, Sub.class, new SubscriptSpan());

} else if (tag.length() == 2 &&

Character.toLowerCase(tag.charAt(0)) == 'h' &&

tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {

handleP(mSpannableStringBuilder);

endHeader(mSpannableStringBuilder);

} else if (mTagHandler != null) {

mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader);

}

}

可以看到,如果不是默认的标签,会调用mTagHandler的handleTag方法。所以,我们可以实现此接口,来解析自己定义的标签类型。

再看一段我实现的对<game>标签进行解析的示例代码:

public class GameTagHandler implements TagHandler {

private int startIndex = 0;

private int stopIndex = 0;

@Override

public void handleTag(boolean opening, String tag, Editable output,

XMLReader xmlReader) {

if (tag.toLowerCase().equals("game")) {

if (opening) {

startGame(tag, output, xmlReader);

} else {

endGame(tag, output, xmlReader);

}

}

}

public void startGame(String tag, Editable output, XMLReader xmlReader) {

startIndex = output.length();

}

public void endGame(String tag, Editable output, XMLReader xmlReader) {

stopIndex = output.length();

output.setSpan(new GameSpan(), startIndex, stopIndex,

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

}

private class GameSpan extends ClickableSpan implements OnClickListener {

@Override

public void onClick(View v) {

// 跳转某页面

}

}

上面这段代码,是对<game> </game>的自定义标签进行解析。

具体调用方法:

textView.setText(Html.fromHtml( 点击<game>这里</game>跳转到游戏 ,

null, new GameTagHandler()));

textView.setClickable(true);

textView.setMovementMethod(LinkMovementMethod.getInstance());

运行后,能够看到文本中的字符串 这里 带了超链接,点击链接后,GameSpan类的onClick()方法被调用。就可以在这个方法中进行跳转了。

赞助本站

人工智能实验室

相关热词: HTML TextView

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港