如果看到這裏說明你對 TextView 已經有了一定的瞭解,至少已經使用過該控件顯示文字過。現在來實現一些複雜一點的效果。 1. 實現可點擊的超鏈接 我們在APP開發過程中會遇到這樣的需求,例如

1. 實現可點擊的超鏈接

我們在APP開發過程中會遇到這樣的需求,例如:

需求

其中標記爲下劃線的爲可點擊,點擊後一般是跳轉一個網頁(這個在這裏不做討論)。面對這樣的需求裏可能已經知道TextView是可以添加下劃線的,你的實現可能是:

By Login, You agree to our Privicy Policy & Terms of use
[TextView]----[TextView]--[TextView]---[TextView]
[By Login, You agree to our ][Privicy Policy][ & ][Terms of use]

然後爲可點擊的 TextView添加下劃線,然後設置點擊事件就ok了。
如果你滿足於這,那麼你可以繼續往後看,看看只用一個TextView 如何實現。

2. 可點擊的超鏈接(基礎)

爲了介紹 SpannableString,我們來用它實現一個簡單的下劃線並設置監聽點擊事件。

簡單使用

        String clickString = "I Love Android!";
        SpannableString spannableString =new SpannableString(clickString);
        spannableString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getActivity(),"Love",Toast.LENGTH_SHORT).show();
            }
        },2,6,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv_tip.setText(spannableString);
        tv_tip.setMovementMethod(LinkMovementMethod.getInstance());

3. 多個可點擊的超鏈接(提高)

這回就要使用一個新的類:SpannableStringBuilder。看到名字就知道,它的作用類似StringBuilder就是把多個SpannableString連接起來。
最後的效果:

進階使用

點擊效果:

點擊效果

代碼實現(關鍵點就是把多個SpannableString連接起來):

        final String linkWord1 = "Android";
        final String linkWord2 = "Are you ok?";
        final String linkWord3 = "think you!";
        String word = "Hello " + linkWord1 + "," + linkWord2 + " I'm fine," + linkWord3;
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(word);
        int index1 = word.indexOf(linkWord1);
        int index2 = word.indexOf(linkWord2);
        int index3 = word.indexOf(linkWord3);
        spannableStringBuilder.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getActivity(), linkWord1, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.RED);       //設置文件顏色
                ds.setUnderlineText(true);      //設置下劃線
            }
        }, index1, index1 + linkWord1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        spannableStringBuilder.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getActivity(), linkWord2, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.GREEN);       //設置文件顏色
                ds.setUnderlineText(true);      //設置下劃線
            }
        }, index2, index2 + linkWord2.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        spannableStringBuilder.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getActivity(), linkWord3, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.BLUE);       //設置文件顏色
                ds.setUnderlineText(false);      //設置下劃線
            }
        }, index3, index3 + linkWord3.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv_tip.setTextSize(14);
        tv_tip.setText(spannableStringBuilder);
        tv_tip.setMovementMethod(LinkMovementMethod.getInstance());

4. 多個可點擊的超鏈接(html)

當然還有另外一種方法,就是使用TextView顯示 html格式的文本,然後處理其中的url,過程還是類似我們上面用到的方法,直接上代碼吧:

       String html = "<p>\n" +
                "   Hello <a href=\"/link/click1\">Android</a>,<a href=\"/link/click2\">Are you ok?</a>I'm fine,<a href=\"/link/click3\">think you!</a>\n" +
                " </p>";

        tv_tip.setText(Html.fromHtml(html));
        tv_tip.setMovementMethod(LinkMovementMethod.getInstance());
        CharSequence text = tv_tip.getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) tv_tip.getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            style.clearSpans(); // should clear old spans
            for (final URLSpan url : urls) {
                // 設置Span
                style.setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        Toast.makeText(getActivity(), url.getURL(), Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        super.updateDrawState(ds);
                        ds.setColor(Color.RED);       //設置文件顏色
                        ds.setUnderlineText(true);      //設置下劃線
                    }
                }, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            tv_tip.setText(style);
        }

效果圖:
因爲我把所有的連接都設置爲紅色,所以顯示的都是紅色,實際中可能進行處理,那時對每個url都進行處理即可。

html實現

這裏我沒有講每個類的細節,因爲我覺得,如果你知道類名,那麼你可以查到對應的官方文檔,官方文檔對api的講解是很詳細的,但是官方很少會結合實際需求告訴你如何實現,可能某一個api你不熟悉你就無法和實際需求聯想起來,希望看了 這篇文章想深入瞭解的可以從 CharSequence 接口(與上面的類緊密聯繫)進行展開。
下一篇講 TextView ImageSpan 實現文字圖片混排。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章