欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析在Android中為TextView增加自定義HTML標(biāo)簽的實(shí)現(xiàn)方法

 更新時(shí)間:2013年05月10日 09:15:53   作者:  
本篇文章是對(duì)在Android中為TextView增加自定義HTML標(biāo)簽的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下

Android中的TextView,本身就支持部分的Html格式標(biāo)簽。這其中包括常用的字體大小顏色設(shè)置,文本鏈接等。使用起來也比較方便,只需要使用Html類轉(zhuǎn)換一下即可。比如:

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


然而,有一種場(chǎng)合,默認(rèn)支持的標(biāo)簽可能不夠用。比如,我們需要在textView中點(diǎn)擊某種鏈接,返回到應(yīng)用中的某個(gè)界面,而不僅僅是網(wǎng)絡(luò)連接,如何實(shí)現(xiàn)?


經(jīng)過幾個(gè)小時(shí)對(duì)android中的Html類源代碼的研究,找到了解決辦法,并且測(cè)試通過。

先看Html類的源代碼中有這樣一段:

復(fù)制代碼 代碼如下:

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

這里定義了一個(gè)接口,接口用于什么呢?

再繼續(xù)看代碼,看到對(duì)Html的tag進(jìn)行解析部分的代碼:

復(fù)制代碼 代碼如下:

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

可以看到,如果不是默認(rèn)的標(biāo)簽,會(huì)調(diào)用mTagHandler的handleTag方法。所以,我們可以實(shí)現(xiàn)此接口,來解析自己定義的標(biāo)簽類型。

再看一段我實(shí)現(xiàn)的對(duì)<game>標(biāo)簽進(jìn)行解析的示例代碼:

復(fù)制代碼 代碼如下:

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) { 
            // 跳轉(zhuǎn)某頁面  
        } 
    }

上面這段代碼,是對(duì)<game>…</game>的自定義標(biāo)簽進(jìn)行解析。


具體調(diào)用方法:

       textView.setText(Html.fromHtml(“點(diǎn)擊<game>這里</game>跳轉(zhuǎn)到游戲”,

              null, new GameTagHandler()));

       textView.setClickable(true);

       textView.setMovementMethod(LinkMovementMethod.getInstance());


運(yùn)行后,能夠看到文本中的字符串“這里”帶了超鏈接,點(diǎn)擊鏈接后,GameSpan類的onClick()方法被調(diào)用。就可以在這個(gè)方法中進(jìn)行跳轉(zhuǎn)了。

相關(guān)文章

  • 簡單好用的Adapter---ArrayAdapter詳解

    簡單好用的Adapter---ArrayAdapter詳解

    這篇文章主要介紹了簡單好用的Adapter---ArrayAdapter詳解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Kotlin學(xué)習(xí)教程之協(xié)程Coroutine

    Kotlin學(xué)習(xí)教程之協(xié)程Coroutine

    這篇文章主要給大家介紹了關(guān)于Kotlin學(xué)習(xí)教程之協(xié)程Coroutine的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • Android中使用ListView繪制自定義表格技巧分享

    Android中使用ListView繪制自定義表格技巧分享

    使用ListView繪制自定義的表格有朋友嘗試過沒有,下面為大家分享下要實(shí)現(xiàn)下圖的效果有幾個(gè)方面,參照著這幾點(diǎn)做了個(gè)簡單的實(shí)現(xiàn)不是問題好了,話不多說看代碼
    2013-06-06
  • Android中3種圖片壓縮處理方法

    Android中3種圖片壓縮處理方法

    這篇文章主要介紹了Android中3種圖片壓縮處理方法,本文講解了質(zhì)量壓縮方法、獲得縮略圖、圖片縮放三種方法并分別給出示例代碼,需要的朋友可以參考下
    2015-06-06
  • Android開發(fā)之開門狗在程序鎖中的應(yīng)用實(shí)例

    Android開發(fā)之開門狗在程序鎖中的應(yīng)用實(shí)例

    這篇文章主要介紹了Android開發(fā)之開門狗在程序鎖中的應(yīng)用,以完整實(shí)例形式分析了程序鎖的使用技巧,需要的朋友可以參考下
    2016-02-02
  • 四種Android數(shù)據(jù)存儲(chǔ)方式

    四種Android數(shù)據(jù)存儲(chǔ)方式

    這篇文章主要為大家詳細(xì)介紹了四種Android數(shù)據(jù)存儲(chǔ)方式,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android布局之表格布局TableLayout詳解

    Android布局之表格布局TableLayout詳解

    這篇文章主要為大家詳細(xì)介紹了Android布局之表格布局TableLayout,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android基于socket實(shí)現(xiàn)的簡單C/S聊天通信功能

    Android基于socket實(shí)現(xiàn)的簡單C/S聊天通信功能

    這篇文章主要介紹了Android基于socket實(shí)現(xiàn)的簡單C/S聊天通信功能,結(jié)合實(shí)例形式分析了Android使用socket實(shí)現(xiàn)客服端與服務(wù)器端數(shù)據(jù)的發(fā)送與接收處理技巧,需要的朋友可以參考下
    2016-10-10
  • Android Toast提示封裝實(shí)例代碼

    Android Toast提示封裝實(shí)例代碼

    這篇文章主要介紹了Android Toast提示封裝實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 使用RecyclerView實(shí)現(xiàn)點(diǎn)贊頭像疊加效果

    使用RecyclerView實(shí)現(xiàn)點(diǎn)贊頭像疊加效果

    這篇文章主要為大家詳細(xì)介紹了使用RecyclerView實(shí)現(xiàn)點(diǎn)贊頭像疊加效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08

最新評(píng)論