激情久久久_欧美视频区_成人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 - 深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格

深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格

2021-01-19 14:41Android開發(fā)網(wǎng) Android

本篇文章是對Android中在同一個TextView中設(shè)置不同的字體風(fēng)格進行了詳細(xì)的分析介紹,需要的朋友參考下

背景介紹
在開發(fā)應(yīng)用過程中經(jīng)常會遇到顯示一些不同的字體風(fēng)格的信息猶如默認(rèn)的lockscreen上面的時間和充電信息。對于類似的情況,可能第一反應(yīng)就是用不同的多個textview來實現(xiàn),對于每個textview設(shè)置不同的字體風(fēng)格以滿足需求。深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格

這里推薦的做法是使用android.text.*;和android.text.style.*;下面的組件來實現(xiàn)richtext:也即在同一個textview中設(shè)置不同的字體風(fēng)格。對于某些應(yīng)用,比如文本編輯,記事本,彩信,短信等地方,還必須使用這些組件才能達(dá)到想到的顯示效果。

主要的基本工具類有android.text.spanned; android.text.spannablestring; android.text.spannablestringbuilder;使用這些類來代替常規(guī)string。spannablestring和spannablestringbuilder可以用來設(shè)置不同的span,這些span便是用于實現(xiàn)rich text,比如粗體,斜體,前景色,背景色,字體大小,字體風(fēng)格等等,android.text.style.*中定義了很多的span類型可供使用。

這是相關(guān)的api的class general hierarchy:深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格

因為spannable等最終都實現(xiàn)了charsequence接口,所以可以直接把spannablestring和spannablestringbuilder通過textview.settext()設(shè)置給textview。
使用方法
當(dāng)要顯示rich text信息的時候,可以使用創(chuàng)建一個spannablestring或spannablestringbuilder,它們的區(qū)別在于spannablestring像一個string一樣,構(gòu)造對象的時候傳入一個string,之后再無法更改string的內(nèi)容,也無法拼接多個spannablestring;而spannablestringbuilder則更像是stringbuilder,它可以通過其append()方法來拼接多個string:

復(fù)制代碼 代碼如下:


spannablestring word = new spannablestring("the quick fox jumps over the lazy dog");
spannablestringbuilder multiword = new spannablestringbuilder();
multiword.append("the quick fox");
multiword.append("jumps over");
multiword.append("the lazy dog");


創(chuàng)建完spannable對象后,就可以為它們設(shè)置span來實現(xiàn)想要的rich text了,常見的span有:
•absolutesizespan(int size) ---- 設(shè)置字體大小,參數(shù)是絕對數(shù)值,相當(dāng)于word中的字體大小
•relativesizespan(float proportion) ---- 設(shè)置字體大小,參數(shù)是相對于默認(rèn)字體大小的倍數(shù),比如默認(rèn)字體大小是x, 那么設(shè)置后的字體大小就是x*proportion,這個用起來比較靈活,proportion>1就是放大(zoom in), proportion<1就是縮小(zoom out)
•scalexspan(float proportion) ---- 縮放字體,與上面的類似,默認(rèn)為1,設(shè)置后就是原來的乘以proportion,大于1時放大(zoon in),小于時縮小(zoom out)
•backgroundcolorspan(int color) ----背景著色,參數(shù)是顏色數(shù)值,可以直接使用android.graphics.color里面定義的常量,或是用color.rgb(int, int, int)
•foregroundcolorspan(int color) ----前景著色,也就是字的著色,參數(shù)與背景著色一致
•typefacespan(string family) ----字體,參數(shù)是字體的名字比如“sans", "sans-serif"等
•stylespan(typeface style) -----字體風(fēng)格,比如粗體,斜體,參數(shù)是android.graphics.typeface里面定義的常量,如typeface.bold,typeface.italic等等。
•strikethroughspan----如果設(shè)置了此風(fēng)格,會有一條線從中間穿過所有的字,就像被劃掉一樣
對于這些sytle span在使用的時候通常只傳上面所說明的構(gòu)造參數(shù)即可,不需要設(shè)置其他的屬性,如果需要的話,也可以對它們設(shè)置其他的屬性,詳情可以參見<>。
spannablestring和spannablestringbuilder都有一個設(shè)置上述span的方法:

復(fù)制代碼 代碼如下:


/**
 * set the style span to spannable, such as spannablestring or spannablestringbuilder
 * @param what --- the style span, such as stylespan
 * @param start --- the starting index of characters to which the style span to apply
 * @param end --- the ending index of characters to which the style span to apply
 * @param flags --- the flag specified to control
 */
setspan(object what, int start, int end, int flags);


其中參數(shù)what是要設(shè)置的style span,start和end則是標(biāo)識string中span的起始位置,而 flags是用于控制行為的,通常設(shè)置為0或spanned中定義的常量,常用的有:
•spanned.span_exclusive_exclusive --- 不包含兩端start和end所在的端點
•spanned.span_exclusive_inclusive --- 不包含端start,但包含end所在的端點
•spanned.span_inclusive_exclusive --- 包含兩端start,但不包含end所在的端點
•spanned.span_inclusive_inclusive--- 包含兩端start和end所在的端點
這里理解起來就好像數(shù)學(xué)中定義區(qū)間,開區(qū)間還是閉區(qū)間一樣的。還有許多其他的flag,可以參考<這里>。這里要重點說明下關(guān)于參數(shù)0,有很多時候,如果設(shè)置了上述的參數(shù),那么span會從start應(yīng)用到text結(jié)尾,而不是在start和end二者之間,這個時候就需要使用flag 0。
linkify
另外,也可以對通過textview.setautolink(int)設(shè)置其linkify屬性,其用處在于,textview會自動檢查其內(nèi)容,會識別出phone number, web address or email address,并標(biāo)識為超鏈接,可點擊,點擊后便跳轉(zhuǎn)到相應(yīng)的應(yīng)用,如dialer,browser或email。linkify有幾個常用選項,更多的請參考<文檔>
•linkify.email_address -- 僅識別出textview中的email在址,標(biāo)識為超鏈接,點擊后會跳到email,發(fā)送郵件給此地址
•linkify.phone_numbers -- 僅識別出textview中的電話號碼,標(biāo)識為超鏈接,點擊后會跳到dialer,call這個號碼
•linkify.web_urls-- 僅識別出textview中的網(wǎng)址,標(biāo)識為超鏈接,點擊后會跳到browser打開此url
•linkify.all -- 這個選項是識別出所有系統(tǒng)所支持的特殊uri,然后做相應(yīng)的操作
權(quán)衡選擇
個人認(rèn)為軟件開發(fā)中最常見的問題不是某個技巧怎么使用的問題,而是何時該使用何技巧的問題,因為實現(xiàn)同一個目標(biāo)可能有n種不同的方法,就要權(quán)衡利弊,選擇最合適的一個,正如常言所云,沒有最好的,只有最適合的。如前面所討論的,要想用不同的字體展現(xiàn)不同的信息可能的解法,除了用style span外還可以用多個textview。那么就需要總結(jié)下什么時候該使用stylespan,什么時候該使用多個textview:
1.如果顯示的是多個不同類別的信息,就應(yīng)該使用多個textview,這樣也方便控制和改變各自的信息,例子就是默認(rèn)lockscreen上面的日期和充電信息,因為它們所承載不同的信息,所以應(yīng)該使用多個textview來分別呈現(xiàn)。
2.如果顯示的是同一類信息,或者同一個信息,那么應(yīng)該使用stylespan。比如,短信息中,要把聯(lián)系人的相關(guān)信息突出顯示;或是想要highlight某些信息等。
3.如果要實現(xiàn)rich text,沒辦法,只能使用style span。
4.如果要實現(xiàn)某些特效,也可以考慮使用stylespan。設(shè)置不同的字體風(fēng)格只是style span的初級應(yīng)用,如果深入研究,可以發(fā)現(xiàn)很多奇妙的功效。
實例

復(fù)制代碼 代碼如下:


<?xml version="1.0" encoding="utf-8"?>
<linearlayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="vertical">
  <scrollview
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
        <linearlayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
     <textview
       android:id="@+id/text_view_font_1"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       />
     <textview
       android:id="@+id/text_view_font_2"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       />
     <textview
       android:id="@+id/text_view_font_3"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       />
     <textview
       android:id="@+id/text_view_font_4"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       />
     <textview
       android:id="@+id/text_view_font_5"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       />
    </linearlayout>
    </scrollview>
</linearlayout>


source code:

復(fù)制代碼 代碼如下:


package com.android.effective;
import java.util.regex.matcher;
import java.util.regex.pattern;
import android.app.activity;
import android.graphics.color;
import android.graphics.typeface;
import android.os.bundle;
import android.text.spannable;
import android.text.spannablestring;
import android.text.spannablestringbuilder;
import android.text.style.absolutesizespan;
import android.text.style.backgroundcolorspan;
import android.text.style.foregroundcolorspan;
import android.text.style.quotespan;
import android.text.style.relativesizespan;
import android.text.style.scalexspan;
import android.text.style.strikethroughspan;
import android.text.style.stylespan;
import android.text.style.typefacespan;
import android.text.style.urlspan;
import android.text.util.linkify;
import android.widget.textview;
public class textviewfontactivity extends activity {
    @override
    public void oncreate(bundle bundle) {
        super.oncreate(bundle);
        setcontentview(r.layout.textview_font_1);

        // demonstration of basic spannablestring and spans usage
        final textview textwithstring = (textview) findviewbyid(r.id.text_view_font_1);
        string w = "the quick fox jumps over the lazy dog";
        int start = w.indexof('q');
        int end = w.indexof('k') + 1;
        spannable word = new spannablestring(w);
        word.setspan(new absolutesizespan(22), start, end,
                spannable.span_inclusive_inclusive);
        word.setspan(new stylespan(typeface.bold), start, end,
                spannable.span_inclusive_inclusive);
        word.setspan(new backgroundcolorspan(color.red), start, end,
                spannable.span_inclusive_inclusive);
        textwithstring.settext(word);

        // demonstration of basic spannablestringbuilder and spans usage
        final textview textwithbuilder = (textview) findviewbyid(r.id.text_view_font_2);
        spannablestringbuilder word2 = new spannablestringbuilder();
        final string one = "freedom is nothing but a chance to be better!";
        final string two = "the quick fox jumps over the lazy dog!";
        final string three = "the tree of liberty must be refreshed from time to time with " +
                "the blood of patroits and tyrants!";
        word2.append(one);
        start = 0;
        end = one.length();
        word2.setspan(new stylespan(typeface.bold_italic), start, end, spannable.span_exclusive_exclusive);
        word2.append(two);
        start = end;
        end += two.length();
        word2.setspan(new foregroundcolorspan(color.cyan), start, end,
                spannable.span_exclusive_exclusive);
        word2.append(three);
        start = end;
        end += three.length();
        word2.setspan(new urlspan(three), start, end, spannable.span_exclusive_exclusive);
        textwithbuilder.settext(word2);

        // troubleshooting when using spannablestringbuilder
        final textview texttroubles = (textview) findviewbyid(r.id.text_view_font_3);
        spannablestringbuilder word3 = new spannablestringbuilder();
        start = 0;
        end = one.length();
        // caution: must first append or set text to spannablestringbuilder or spannablestring
        // then set the spans to them, otherwise, indexoutofboundexception is thrown when setting spans
        word3.append(one);
        // for absolutesizespan, the flag must be set to 0, otherwise, it will apply this span to until end of text
        word3.setspan(new absolutesizespan(22), start, end, 0);//spannable.span_inclusive_inclusive);
        // for backgroundcolorspanspan, the flag must be set to 0, otherwise, it will apply this span to end of text
        word3.setspan(new backgroundcolorspan(color.dkgray), start, end, 0); //spannable.span_inclusive_inclusive);
        word3.append(two);
        start = end;
        end += two.length();
        word3.setspan(new typefacespan("sans-serif"), start, end,
                spannable.span_inclusive_inclusive);
        // todo: sometimes, flag must be set to 0, otherwise it will apply the span to until end of text
        // which might has nothing to do with specific span type.
        word3.setspan(new stylespan(typeface.bold_italic), start, end, 0);//spannable.span_inclusive_inclusive);
        word3.setspan(new scalexspan(0.618f), start, end, spannable.span_inclusive_inclusive);
        word3.setspan(new strikethroughspan(), start, end, 0);//spannable.span_inclusive_inclusive);
        word3.setspan(new foregroundcolorspan(color.cyan), start, end, spannable.span_inclusive_inclusive);
        word3.setspan(new quotespan(), start, end, 0); //spannable.span_inclusive_inclusive);
        word3.append(three);
        start = end;
        end += three.length();
        word3.setspan(new relativesizespan((float) math.e), start, end, spannable.span_inclusive_inclusive);
        word3.setspan(new foregroundcolorspan(color.blue), start, end, spannable.span_inclusive_inclusive);
        texttroubles.settext(word3);

        // highlight some patterns
        final string four = "the gap between the best software engineering " +
                "practice and the average practice is very wide¡ªperhaps wider " +
                " than in any other engineering discipline. a tool that disseminates " +
                "good practice would be important.¡ªfred brooks";
        final pattern highlight = pattern.compile("the");
        final textview texthighlight = (textview) findviewbyid(r.id.text_view_font_4);
        spannablestring word4 = new spannablestring(four);
        matcher m = highlight.matcher(word4.tostring());
        while (m.find()) {
            word4.setspan(new stylespan(typeface.bold_italic), m.start(), m.end(),
                    spannable.span_inclusive_inclusive);
            word4.setspan(new foregroundcolorspan(color.red), m.start(), m.end(),
                    spannable.span_inclusive_inclusive);
            word4.setspan(new strikethroughspan(), m.start(), m.end(),
                    spannable.span_inclusive_inclusive);
        }
        texthighlight.settext(word4);

        // set numbers, urls and e-mail address to be clickable with textview#setautolinkmask
        final textview textclickable = (textview) findviewbyid(r.id.text_view_font_5); 
        final string contact = "email: [email protected]\n" +
                "phone: +47-24885883\n" +
                "fax: +47-24885883\n" +
                "http: www.microsoft.com/mvp.asp";
        // set the attribute first, then set the text. otherwise, it won't work
        textclickable.setautolinkmask(linkify.all); // or set 'android:autolink' in layout xml
        textclickable.settext(contact);
    }
}


the results:

 

 

深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格深入理解TextView實現(xiàn)Rich Text--在同一個TextView設(shè)置不同字體風(fēng)格

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 草逼一区| 国产亚洲综合一区二区 | 成年男女免费视频 | 快播av在线 | 色视频在线播放 | 黄色成人小视频 | 国产合集91合集久久日 | 激情视频免费看 | 福利免费在线观看 | 久久久久久久久浪潮精品 | 日本成人一区 | 2018亚洲男人天堂 | 国产99久久久久久免费看农村 | 成人免费精品视频 | 免费性爱视频 | 高清国产在线 | 精品三区视频 | 超碰97人| 一级黄色免费观看 | 中文字幕国产欧美 | 麻豆视频网 | 国产精品久久久久国产精品三级 | 亚洲一级电影在线观看 | 蜜桃成品人免费视频 | 美女喷水网站 | 一区二区三区欧洲 | 色屁屁xxxxⅹ免费视频 | 久久艹艹艹 | 黄色美女网站免费看 | 国产精品久久久久久久久久久久久久久久 | 在线播放免费人成毛片乱码 | 欧美日韩视频在线播放 | 欧美一级特级 | 粉色视频污 | 91久久久久久久久久久久久 | 亚洲精品aa | 国产精品久久久久久久久久久久午夜 | 成人精品一区二区 | 亚洲欧美成aⅴ人在线观看 av免费在线播放 | 毛片免费看的 | 久久福利小视频 |