關於TextView 的富文本實現方式,有2中,一種使用Html來作,一種是使用SpannableString;html
SpannableString太麻煩了,這裏有參考:java
http://www.chawenti.com/articles/16016.htmlandroid
關於 TextView使用Html,能夠參考 這篇blog網絡
http://blog.csdn.net/johnsonblog/article/details/7741972#commentside
String類是CharSequence的子類,在CharSequence子類中有一個接口Spanned,即相似html的帶標記的文本,咱們能夠用它來在TextView中顯示html。但在上面Android源碼註釋中有說起TextView does not accept HTML-like formatting。
學習
android.text.Html類共提供了三個方法,能夠到Android幫助文檔查看。ui
public static Spanned fromHtml (String source)
public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
public static String toHtml (Spanned text)this
常常使用的是第一個方法:url
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的另外第二個重構方法:spa
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());