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

首頁 > 系統 > Android > 正文

解析在Android中為TextView增加自定義HTML標簽的實現方法

2020-04-11 12:25:13
字體:
來源:轉載
供稿:網友

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

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


然而,有一種場合,默認支持的標簽可能不夠用。比如,我們需要在textView中點擊某種鏈接,返回到應用中的某個界面,而不僅僅是網絡連接,如何實現?


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

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

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

再繼續看代碼,看到對Html的tag進行解析部分的代碼:

復制代碼 代碼如下:

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

可以看到,如果不是默認的標簽,會調用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) { 
            // 跳轉某頁面  
        } 
    }

上面這段代碼,是對<game>…</game>的自定義標簽進行解析。


具體調用方法:

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

              null, new GameTagHandler()));

       textView.setClickable(true);

       textView.setMovementMethod(LinkMovementMethod.getInstance());


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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品亚洲欧美导航| 国产精品青草久久久久福利99| 亚洲国产婷婷香蕉久久久久久| 91精品视频免费看| 中文字幕少妇一区二区三区| 精品伊人久久97| 欧美亚洲视频在线观看| 91成人国产在线观看| 午夜剧场成人观在线视频免费观看| 孩xxxx性bbbb欧美| 91在线免费视频| 最近2019中文字幕大全第二页| 91精品久久久久久久久青青| 成人免费黄色网| 欧美国产视频日韩| 免费97视频在线精品国自产拍| 欧美人与性动交a欧美精品| 久久成人亚洲精品| 欧美资源在线观看| 日韩一区二区在线视频| 国产精品激情av在线播放| 日韩免费不卡av| 日韩中文有码在线视频| 亚洲国产精品中文| 欧美激情一区二区三区成人| 国产欧美一区二区三区久久人妖| 亚洲一区二区免费在线| 亚洲国产精品久久久| 日韩欧美在线网址| 91精品国产高清| 国内精品伊人久久| 日韩免费观看高清| 久久久噜噜噜久久中文字免| 欧美大肥婆大肥bbbbb| 久久精品99国产精品酒店日本| 国产精品久久久久91| 日本精品性网站在线观看| 另类色图亚洲色图| 日韩av网站导航| 5252色成人免费视频| 国产精品v片在线观看不卡| 精品视频中文字幕| 久久97精品久久久久久久不卡| 欧美日韩电影在线观看| 久久艹在线视频| 九九九久久国产免费| 国产精品视频久久久久| 18一19gay欧美视频网站| 一本大道亚洲视频| 欧美专区日韩视频| 亚洲天堂影视av| 久久久久久亚洲| 亚洲色图50p| 久久久免费电影| 日韩免费av片在线观看| 中文字幕欧美日韩在线| 国产91色在线播放| 欧美性生交大片免费| 国产精品久久久久久久久久久不卡| 欧美在线一级va免费观看| 亚洲精品久久7777777| 欧美成人激情视频免费观看| 国产色婷婷国产综合在线理论片a| 中文字幕日韩有码| 久久亚洲综合国产精品99麻豆精品福利| 国产va免费精品高清在线| 欧美肥臀大乳一区二区免费视频| 久久精品视频免费播放| 日韩精品视频在线播放| 欧美激情亚洲综合一区| 精品久久久香蕉免费精品视频| 久久人人爽人人| 精品久久久精品| 国产精品成人一区| 91精品视频一区| 久久久中文字幕| 亚洲欧美一区二区三区在线| 久久中国妇女中文字幕| 日韩精品视频在线观看网址| 久久精品中文字幕| 日韩亚洲第一页| 欧美大片在线免费观看| 欧美怡春院一区二区三区| 日韩av不卡电影| 国产91精品视频在线观看| 中国人与牲禽动交精品| 欧美日韩国产一区在线| 国产精品18久久久久久首页狼| 国产成人一区二区在线| 中日韩美女免费视频网站在线观看| 日韩精品视频免费专区在线播放| 成人网在线观看| 成人午夜在线观看| 国产精品视频免费在线| 久久人人爽人人爽人人片亚洲| 欧美激情第一页xxx| 欧美日韩亚洲国产一区| 欧美在线亚洲一区| 77777亚洲午夜久久多人| 日韩女优人人人人射在线视频| 欧美激情第一页xxx| 国产丝袜一区视频在线观看| 精品中文字幕乱| 成人免费视频xnxx.com| 国产美女久久久| 久久网福利资源网站| 国产视频自拍一区| 欧美小视频在线| 4438全国成人免费| 久久国产精品久久国产精品| 日韩经典中文字幕在线观看| 久久亚洲精品成人| 国产精品欧美日韩一区二区| 精品久久久久久久久中文字幕| 奇米影视亚洲狠狠色| 亚洲人成电影网站色| 中文字幕亚洲欧美日韩在线不卡| 中文字幕不卡在线视频极品| 久久中文久久字幕| 精品免费在线视频| 国产成人精品a视频一区www| 一区二区av在线| 成人黄色片网站| 欧美一级视频免费在线观看| 欧美精品一区三区| 欧美性猛交xxxx黑人| 亚洲国产精品专区久久| 欧美激情二区三区| 欧美午夜女人视频在线| 最好看的2019的中文字幕视频| yw.139尤物在线精品视频| 欧美最猛黑人xxxx黑人猛叫黄| 久久久91精品国产一区不卡| 亚洲精品成人久久久| 精品一区二区三区四区在线| 亚洲白虎美女被爆操| 国产激情久久久| 国产精品极品美女在线观看免费| 欧美日韩国产成人| 国产成人avxxxxx在线看| 最近2019好看的中文字幕免费| 亚洲深夜福利网站| 欧美性视频网站| 欧美性猛交xxxx偷拍洗澡| 97久久精品视频| 欧美成人性色生活仑片| 一个人看的www久久| 一本色道久久88亚洲综合88| 国产盗摄xxxx视频xxx69| 欧美精品videossex性护士| 91精品国产高清久久久久久| 国产一区香蕉久久| 亚洲激情国产精品| 色偷偷av一区二区三区乱| 国产成人精品日本亚洲专区61| 51色欧美片视频在线观看| 97人洗澡人人免费公开视频碰碰碰| 国产色综合天天综合网| 国产精品一区二区3区| 国产精品自产拍在线观看中文| 欧美丝袜一区二区| 久久久女人电视剧免费播放下载| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲国产欧美一区二区丝袜黑人|