国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

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

2020-04-11 12:25:13
字體:
供稿:網(wǎng)友

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)某頁(yè)面  
        } 
    }

上面這段代碼,是對(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)了。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 油尖旺区| 衡东县| 浙江省| 长武县| 稻城县| 河池市| 临泉县| 区。| 富阳市| 梁山县| 辽宁省| 东光县| 虞城县| 阿合奇县| 牡丹江市| 六安市| 淮南市| 桑日县| 图片| 福清市| 敖汉旗| 香河县| 台北市| 江川县| 普陀区| 东乡族自治县| 通州市| 罗平县| 哈尔滨市| 五指山市| 镇赉县| 阿图什市| 凌云县| 陇西县| 武威市| 玉溪市| 方城县| 商都县| 灌阳县| 荥经县| 泽普县|