亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

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

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

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

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


然而,有一種場合,默認(rèn)支持的標(biāo)簽可能不夠用。比如,我們需要在textView中點擊某種鏈接,返回到應(yīng)用中的某個界面,而不僅僅是網(wǎng)絡(luò)連接,如何實現(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進行解析部分的代碼:

復(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方法。所以,我們可以實現(xiàn)此接口,來解析自己定義的標(biāo)簽類型。

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

復(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)簽進行解析。


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

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

              null, new GameTagHandler()));

       textView.setClickable(true);

       textView.setMovementMethod(LinkMovementMethod.getInstance());


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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
神马亚洲视频| 99热国产免费| 久久69成人| 国产情人节一区| 91玉足脚交白嫩脚丫| 4hu四虎永久网址| 国产人妻精品久久久久野外| 日韩在线免费播放| 久草在.com| 日韩你懂的在线播放| 欧美亚洲动漫精品| 国产破处视频在线观看| 色偷偷成人一区二区三区91| 精品无人区一区二区三区| 成人超碰在线| 成人精品第一区二区三区| 91精品在线播放| 你懂的在线免费观看| 国产成人禁片免费观看视频| 一道精品视频一区二区三区图片| 国产无码精品在线播放| 成人性爱视频在线观看| 宅男噜噜噜66国产日韩在线观看| 中文字幕一区久久| 国产精品igao激情视频| 亚洲啊v在线观看| 欧美体内she精视频| 日韩夫妻性生活xx| 淫行教师动漫| 亚洲一区二区四区蜜桃| 日本精品另类| 国产亚洲精品女人久久久久久| 欧洲成人午夜精品无码区久久| 美女黄色一级视频| 国产视频亚洲视频| 国产精品视频精品| 熟妇高潮一区二区高潮| 超碰97在线播放| 亚洲天堂免费视频| 国产精品x453.com| 国产欧美日韩一区二区三区| 亚州av电影免费在线观看| 日韩va亚洲va欧美va清高| 一本一道久久a久久精品综合| 亚洲国产成人久久综合一区| 开心九九激情九九欧美日韩精美视频电影| 国产盗摄一区二区| 91po在线观看91精品国产性色| 99国产精品久久久久久久久久久| 国产探花一区二区| 中文字幕视频免费在线观看| 性生活一级大片| 免费美女久久99| 99久久99久久精品免费看小说.| 国产视频福利| 中文字幕影音先锋| 日韩午夜精品视频| 亚洲人成网站在线观看播放| 美国黑人一级大黄| 老司机精品视频在线观看6| 最近中文字幕在线观看视频| 国产91久久婷婷一区二区| 欧美在线观看视频一区二区| 国产在线一区二区综合免费视频| 国产视频网站一区二区三区| av男人的天堂在线| 国内精品久久久久久久久蜜桃| 91黄色小网站| 国产精品福利导航| 国产精品久久精品国产| 久草免费在线| 色av中文字幕| 你懂的在线观看视频网站| 国产精品主播在线观看| 人妻少妇精品一区二区三区| 俺来俺也去www色在线观看| av网站在线免费看| 国产美女在线一区二区三区| 免费视频一区二区| 日韩国产欧美精品一区二区三区| 北条麻妃99精品青青久久| 亚洲午夜精品久久久| 成人性生交大片免费看中文| 色综合男人天堂| 极品尤物久久久av免费看| 中文字幕制服丝袜成人av| 午夜性色福利影院| 婷婷福利视频导航| 一区二区三区精品| 亚洲天堂男人av| 残酷重口调教一区二区| 97精品国产福利一区二区三区| 黄色视屏免费在线观看| 欧美日韩大片在线观看| 久久精彩视频| 色999韩欧美国产综合俺来也| 免费日韩av| 亚洲欧美中文日韩v在线观看| 成人黄色免费片| 欧美综合色免费| 五月婷婷综合在线观看| 国产一区在线免费观看| 日韩欧美电影在线观看| 粉嫩绯色av一区二区在线观看| 国产一级黄色| 中文字幕av一区二区三区谷原希美| 男人操女人免费| 麻豆精品一区二区综合av| 精品不卡一区| 成人激情电影在线看| 亚洲人成电影在线观看网| 国产97色在线 | 日韩| 成人精品国产| 午夜av噜噜噜噜噜噜| 中文在线观看免费| 国产二区视频在线播放| 精品综合久久| 少妇精品视频一区二区免费看| 日韩精品看片| 国产精品久久三区| 成年网站免费在线观看| aa片在线观看视频在线播放| 久久99偷拍| 欧美高清在线视频观看不卡| 欧美一卡二卡在线| 中文字幕在线官网| 日韩一区二区免费在线电影| 无码人妻aⅴ一区二区三区日本| 天天操天天干天天做| 狠狠色香婷婷久久亚洲精品| 免费av观看网站| 不卡的免费av| 在线播放高清视频www| 日韩欧美视频一区| 97不卡在线视频| 日本熟女毛茸茸| 初尝黑人巨炮波多野结衣电影| 欧美xxxx性xxxxx高清视频| 欧美疯狂性受xxxxx喷水图片| 成人精品在线观看| 午夜a一级毛片亚洲欧洲| 欧美人体大胆444www| 一区二区三区欧美在线观看| 国产精品99导航| 国产白袜脚足j棉袜在线观看| 伊人成人开心激情综合网| 国内精品国产成人国产三级| 一区二区三区精品国产| 美洲精品一卡2卡三卡4卡四卡| 狠狠干在线视频| 国产免费色视频| 实拍女处破www免费看| 免费在线成人| 日韩一区二区三区精品视频| 精品国内自产拍在线视频| 亚洲国产精品成人va在线观看| 波多野结衣中文字幕在线| 国产精品网站大全| 亚洲精品久久久久中文字幕欢迎你| 成人精品一区二区不卡视频| 国产欧美一区二区三区在线看蜜臀| 可以看毛片的网址| 99精品视频一区二区三区| 国产欧美日韩一区二区三区| 制服丝袜亚洲网站| 亚洲第一区在线| 看欧美日韩国产| 精品国产18久久久久久洗澡| 国产精品久久久久7777按摩| 狠狠综合久久av一区二区蜜桃| 国产精品嫩草影院av蜜臀| 亚洲色图 在线视频| 日本不卡一区二区三区四区| 国产免费一区二区三区在线观看| 亚洲精品二区| 另类国产ts人妖高潮视频| 狠狠久久伊人| 丰满的护士2在线观看高清| 亚洲视频在线免费播放| 超碰中文字幕在线观看| 日日狠狠久久偷偷综合色| 欧洲另类一二三四区| 李宗瑞系列合集久久| 国产精品国产一区二区三区四区| 精品国产91亚洲一区二区三区婷婷| 中文字幕精品一区二区精| 亚洲国产一区二区视频| 国产精品伦理久久久久久| 日韩一级大片| 国产视频久久久| 欧美亚洲一二三区| 丰满人妻妇伦又伦精品国产| 久久成人精品无人区| 老司机精品视频在线播放| 深夜福利日韩在线看| 国产大片一区| 免费一级黄色大片| 男人资源网站| 97超超碰碰| 欧美黑人疯狂性受xxxxx喷水| 蜜桃极品自拍av| 日本黄大片在线观看| 亚洲宅男天堂在线观看无病毒| 国产探花在线播放| 有码在线播放| 99国产精品视频免费观看| 乱妇乱女熟妇熟女网站| 毛片视频网站在线观看| 国产成人激情小视频| 极品盗摄国产盗摄合集| 91影院在线免费观看| 欧美在线91| 免费日韩电影在线观看| 欧洲av在线精品| 第九色区av在线| 欧美日韩视频不卡| 日韩激情中文字幕| 亚洲精品极品| 一本大道综合伊人精品热热| 欧美丝袜激情| 久久久久亚洲av无码专区喷水| 日韩理论电影| www.国产高清| 日韩美女一区二区三区在线观看| 久久99精品久久久久久琪琪| 亚洲伊人影院| 狠狠躁少妇一区二区三区| 亚洲自拍偷拍图区| 国产高清大尺度一区二区不卡| 在线一区二区不卡| 日韩电影视频免费| 丁香六月综合激情| 亚洲精品中文字幕乱码三区不卡| 欧美成人有码| 日本高清成人vr专区| 久草热视频在线观看| 伊人久久亚洲美女图片| 92看片淫黄大片一级| 成人h视频在线观看播放| 疯狂做受xxxx高潮欧美日本| 国产真实精品久久二三区| 日韩午夜电影av| h视频网站在线观看| 国产精品热视频| 亚洲va欧美va在线观看| 精品免费国产一区二区| 欧美激情在线免费观看| 国产精品久久久久毛片| 瑟瑟视频在线| www.国产视频.com| 亚洲丶国产丶欧美一区二区三区| 久久久国际精品| 视频一区二区三区在线观看| 精品视频在线一区二区在线| av色综合久久天堂av色综合在| 极品美妇后花庭翘臀娇吟小说| 小早川怜子影音先锋在线观看| 国产精品女主播av| 一级在线观看| 少妇激情一区二区三区视频| 四虎影视精品| 在线视频观看国产| 天堂8中文在线最新版在线| 成年网站在线观看视频| 精品国产一区二区三区久久影院| 免费观看成人www动漫视频| 亚洲va国产天堂va久久en| 蜜桃免费在线视频| 免费国产精品视频| 欧美日韩一区二区三区| 高清成人在线观看| 999久久久精品一区二区| 做爰视频毛片视频| 浴室偷拍美女洗澡456在线| 亚洲国产日韩一区二区| 国产亚洲va综合人人澡精品| 日本一区精品久久久久影院| 青青草成人免费在线视频| japanese在线视频| 黄色av网址在线观看| 3d动漫精品啪啪一区二区下载| 日本搞黄视频| 国产一区二区三区久久久久久久久| 亚洲精品乱码久久久久久久久| jizz视频| 99在线精品免费视频九九视| 亚洲精品成人av| 色欲av伊人久久大香线蕉影院| 亚洲成人短视频| 午夜私人影院在线观看| 亚洲综合av一区| 一区二区高清视频在线观看| 欧美一级精品在线| 精品国产91乱码一区二区三区四区| 亚洲一区二三区| 久久久无码精品亚洲日韩按摩| 丁香另类激情小说| 日韩精品久久理论片| 久久精品欧美一区二区三区不卡| 粉嫩av懂色av蜜臀av分享| 亚洲第一天堂av| 日本熟女毛茸茸| 日韩一区二区三区久久| 国产极品人妖在线观看| 免费在线播放电影| 日本不卡高字幕在线2019| 最新中文字幕久久| 国产综合色在线| 97福利电影| 三级视频在线| 欧美日一区二区三区在线观看国产免| 亚洲每日在线| 国产三级视频在线看| 亚洲成人av综合| 亚洲成色777777女色窝| 日本福利一区| 日日噜噜夜夜狠狠视频欧美人| 日韩精品第一| 亚洲高清在线观看一区| 欧美疯狂做受xxxx高潮| 四虎国产精品免费| 久久久久久久久99精品| 一二三四区视频| 亚洲午夜精品久久久久久高潮| 波多野结衣在线观看一区二区三区| 99鲁鲁精品一区二区三区| 亚洲AV成人无码网站天堂久久| 欧美系列在线观看|