源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

解析在Android中为TextView增加自定义HTML标签的实现方法

  • 时间:2020-03-19 16:05 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:解析在Android中为TextView增加自定义HTML标签的实现方法
Android中的TextView,本身就支持部分的Html格式标签。这其中包括常用的字体大小颜色设置,文本链接等。使用起来也比较方便,只需要使用Html类转换一下即可。[b]比如:[/b] textView.setText(Html.fromHtml(str)); 然而,有一种场合,默认支持的标签可能不够用。比如,我们需要在textView中点击某种链接,返回到应用中的某个界面,而不仅仅是网络连接,如何实现? 经过几个小时对android中的Html类源代码的研究,找到了解决办法,并且测试通过。 [b]先看Html类的源代码中有这样一段: [/b]
[u]复制代码[/u] 代码如下:
/**     * 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); 
[b]这里定义了一个接口,接口用于什么呢?[/b] 再继续看代码,看到对Html的tag进行解析部分的代码:
[u]复制代码[/u] 代码如下:
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>标签进行解析的示例代码:
[u]复制代码[/u] 代码如下:
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>的自定义标签进行解析。 [b]具体调用方法:[/b]        textView.setText(Html.fromHtml(“点击<game>这里</game>跳转到游戏”,               null, new GameTagHandler()));        textView.setClickable(true);        textView.setMovementMethod(LinkMovementMethod.getInstance()); 运行后,能够看到文本中的字符串“这里”带了超链接,点击链接后,GameSpan类的onClick()方法被调用。就可以在这个方法中进行跳转了。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部