TextView使用HTML标签

关于TextView 的富文本实现方式,有2中,一种使用Html来做,一种是使用SpannableString;

SpannableString太麻烦了,这里有参考:

http://www.chawenti.com/articles/16016.html


关于 TextView使用Html,可以参考 这篇blog

http://blog.csdn.net/johnsonblog/article/details/7741972#comments

String类是CharSequence的子类,在CharSequence子类中有一个接口Spanned,即类似html的带标记的文本,我们可以用它来在TextView中显示html。在上面Android源码注释中有提及TextView does not accept HTML-like formatting。

   android.text.Html类共提供了三个方法,可以到Android帮助文档查看。


public static Spanned fromHtml (String source)
public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
public static String toHtml (Spanned text)


经常使用的是第一个方法:

       TextView tv=(TextView)findViewById(R.id.textView1);  
        String html="<html><head><title>TextView
使用HTML</title></head><body><p><strong>强
调</strong></p><p><em>斜体</em></p>"  
                +"<p><a href=\"http://www.dreamdu.com
/xhtml/\">超链接HTML入门</a>学习HTML!<
/p><p><font color=\"#aabb00\">颜色1"  
                +"</p><p><font color=\"#00bbaa
\">颜色2</p><h1>标题1</h1><h3>标题2<
/h3><h6>标题3</h6><p>大于>小于<</p><p>" +  
                "下面是网络图片</p><img src=\"http://avatar.csdn.net/0/3/8/2_zhang957411207.jpg\"/></body></html>";  
          
        tv.setMovementMethod(ScrollingMovementMethod.getInstance());//滚动  
        tv.setText(Html.fromHtml(html));


要实现图片的显示需要使用Html.fromHtml的另外第二个重构方法:

public static Spanned fromHtml (String source, Html.ImageGetterimageGetter, Html.TagHandler tagHandler)

其中Html.ImageGetter是一个接口,我们要实现此接口,在它的getDrawable(String source)方法中返回图片的Drawable对象才可以。

ImageGetter imgGetter = new Html.ImageGetter() {
        public Drawable getDrawable(String source) {
              Drawable drawable = null;
              URL url;  
              try {   
                  url = new URL(source);  
                  drawable = Drawable.createFromStream(url.openStream(), "");  //获取网路图片
              } catch (Exception e) {  
                  return null;  
              }  
              drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
                            .getIntrinsicHeight());
              return drawable; 
        }
};


这里主要是实现了Html.ImageGetter接口,通过图片的URL地址获取相应的Drawable实例。

上面介绍的是显示网络上的图片,但如何显示本地的图片呢:

   ImageGetter imgGetter = new Html.ImageGetter() {
        public Drawable getDrawable(String source) {
              Drawable drawable = null;
               
              drawable = Drawable.createFromPath(source); //显示本地图片
              drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
                            .getIntrinsicHeight());
              return drawable; 
        }
};

只需将source改为本地图片的路径便可,在这里我使用的是:

    String source;
    source=getFilesDir()+"/ic_launcher.png";

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

这里主要讲一种场合的使用,来源

http://www.jb51.net/article/36643.htm

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

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


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.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.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) {  
            // 跳转某页面  ,自己实现跳转的动作,就可以点击TextView中的指定文字进行自定义的动作的了 
        }  
    }

然后在工程中调用方法:

       textView.setText(Html.fromHtml(“点击<game>这里</game>跳转到游戏”,null, new GameTagHandler()));

       textView.setClickable(true);

       textView.setMovementMethod(LinkMovementMethod.getInstance());


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。