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 for each

// 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方法。所以,我们可以实现此接口,来解析自己定义的标签类型。

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

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) {

// 跳转某页面

}

}

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

具体调用方法:

textView.setText(Html.fromHtml(“点击这里跳转到游戏”,

null, new GameTagHandler()));

textView.setClickable(true);

textView.setMovementMethod(LinkMovementMethod.getInstance());

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

原文链接:

http://blog.csdn.net/arui319/article/details/6709424

android 如何去掉自定义标签页,Android中为TextView增加自定义的HTML标签相关推荐

  1. Android中为TextView增加自定义的HTML标签

    为什么80%的码农都做不了架构师?>>>    Android中的TextView,本身就支持部分的Html格式标签.这其中包括常用的字体大小颜色设置,文本链接等.使用起来也比较方便 ...

  2. html ie 新标签页打开,教你IE浏览器恢复以前新标签打开样式在win10中方法 | 专业网吧维护...

    我们在win10系统的使用中,很多的小伙伴都是需要安装不同的电脑的浏览器来使用的,但是系统自带的IE浏览器就是很多的小伙伴也在使用的,在更新升级IE浏览器以后有小伙伴页面标签的和以前的不一样了,想要设 ...

  3. android 自定义banner样式_Android中Banner的指示器自定义View

    Banner是我们经常会遇到的一个功能,有很多是需要支持滑动是有个当前的指示器界面,一般如果为了图省事的方案可以用LinearLayout然后不断的在里面添加View,把背景通过shape来设置圆形. ...

  4. android自定义引导页,Android仿大众点评引导页(ViewPage)+主页面(Fragment)的实现

    大家好,今天主要是实现仿大众点评引导页和主页面以及城市定位的实现,主要使用ViewPager+Fragment+SharedPreferences,实现了第一次打开程序出现引导页,再次打开跳过引导页, ...

  5. html自定义js程序,JS中微信小程序自定义底部弹出框

    实现微信小程序底部弹出框效果,代码分为html,css和js两部分,具体代码详情大家参考下本文. html CSS .commodity_screen { width: 100%; height: 1 ...

  6. android 多个标签页,Android一个标签页的实现

    最近要实现一个类似于下面的页面 想着每次都要自己重新写,太麻烦了,这里记录一下自己写的自定义的view.一开始本来准备用ConstraintLayout的,但是这货addview的时候总有bug,就用 ...

  7. 微博机型Android怎么去掉,如何设置微博来源中显示出的手机型号 怎么去掉微博来源中的android字样...

    如何设置微博来源中显示出的手机型号 怎么去掉微博来源中的android字样 微博是一款分享.传播.获取实时信息的社交网络平台,是现在年轻人最爱的一款社交App,可是,不少朋友还不知道怎么设置微博来源中 ...

  8. android 获取手机a标签页,Android关于对Jsoup抓取a标签和br标签之间的解决办法...

    Jsoup官方给出的文档,链接:http://www.open-open.com/jsoup/ 描述问题: 学校教务处系统中,我想获取所有科目以及对应的成绩,因此我采用了Jsoup抓取 采集成绩:fe ...

  9. android 模仿uc标签页,android模仿UC首页天气效果

    这个效果写了两边才搞出来,写第一遍的时候是凭着自己对这个效果的记忆去写的,重写了ScrollView,在初始化完毕给它强制添加了一个View,并设置paddingtop为-view的高度隐藏它,然后通 ...

最新文章

  1. 别再写 main 方法测试了,太 Low!这才是专业 Java 测试方法!
  2. 手把手教你用python抢票回家过年 !(附代码)
  3. Nginx服务器版本升级需求分析
  4. mysql查询添加数据库表_MySQL数据库篇之表的增删改查
  5. python学习笔记之读取配置文件【转自https://my.oschina.net/u/3041656/blog/793467】
  6. 手机怎么解决同ip多账号_原神手游如何多开刷初始号赚钱技巧攻略 | 兔子IP
  7. 【蓝牙串口无线烧写程序】适用于STM32F103和STM32F107的Bootloader
  8. MATLAB 产生带宽信号
  9. 六月份大学毕业,却感觉自己什么都不会。很迷茫,怎么办?
  10. [GIS热点] 3S技术集成-新技术革命下集成模式
  11. 七十七、java版商城之直播短视频带货Spring Cloud+SpringBoot+mybatis+uniapp b2b2c o2o 多商家入驻商城 直播带货商城 电子商务
  12. 第一型曲线和曲面积分总结
  13. iOS - 添加代码片段(Code Snippets)
  14. 消息称苹果最快将于2022年推出折叠屏iPhone
  15. 校园访客登记管理系统设计与实现 java
  16. 论文查重系统需要注意哪些细节问题?
  17. ExoPlayer记录学习
  18. Ubuntu显示WiFi信号强度
  19. 树形选择变成表格树选择
  20. 软件系统问题排查的一般流程

热门文章

  1. 系统搜索功能不能使用,弹出“无法找到运行搜索助理需要的一个文件”
  2. 《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL
  3. Django ORM 中的批量操作
  4. 快速了解什么是自然语言处理
  5. 《精通Linux设备驱动程序开发》——1.7 编译内核
  6. Mysql 批量写入数据 性能优化
  7. Android根据baidu Android定位SDK实现定位
  8. android 中的aidl
  9. MapInfo数据到ARCGIS数据Shapefile的转换
  10. laravel中Request、Session、Response、Middelware