激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Android - 解析在Android中為TextView增加自定義HTML標(biāo)簽的實(shí)現(xiàn)方法

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

2021-01-15 15:06Android開發(fā)網(wǎng) Android

本篇文章是對在Android中為TextView增加自定義HTML標(biāo)簽的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下

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

比如:textView.setText(Html.fromHtml(str));


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


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

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


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

 

再繼續(xù)看代碼,看到對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)簽,會調(diào)用mTagHandler的handleTag方法。所以,我們可以實(shí)現(xiàn)此接口,來解析自己定義的標(biāo)簽類型。

 

再看一段我實(shí)現(xiàn)的對<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)某頁面  
        } 
    }


上面這段代碼,是對<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)用。就可以在這個方法中進(jìn)行跳轉(zhuǎn)了。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人高潮免费观看精品 | 羞羞视频免费网站 | 国产一国产一级毛片视频 | 精品国产一区二区三区在线观看 | 草逼一区 | 美女视频网站黄色 | 国产精品一区二区x88av | h视频在线免费观看 | 亚洲3atv精品一区二区三区 | 国产女同疯狂激烈互摸 | 在线成人av观看 | 午夜九九九 | 亚洲成人高清在线观看 | 色中色激情影院 | 一区二区网 | 特级黄色一级毛片 | 欧美日韩亚洲视频 | 性毛片视频 | 国产成人在线免费视频 | 久久久久一区二区三区 | 欧美激情精品久久久久久久久久 | 国产精品亚洲激情 | 日本在线免费观看 | 欧美精品激情在线 | 毛片大全 | 亚洲人成网站免费播放 | 午夜视频在线在免费 | 欧美一级黄色录像片 | 黄色片一区二区 | 国产午夜精品一区二区三区视频 | 国产女厕一区二区三区在线视 | 成人网视频 | 国产精品伊人久久 | 777zyz色资源站在线观看 | 亚洲影院久久久av天天蜜桃臀 | 免费激情网址 | 国产1区在线观看 | 久久恋 | 在线a毛片免费视频观看 | www视频免费观看 | 久久精品无码一区二区日韩av |