欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android設(shè)置TextView樣式SpannableString教程

 更新時(shí)間:2023年02月14日 16:25:45   作者:流浪漢kylin  
這篇文章主要為大家介紹了Android設(shè)置TextView樣式SpannableString教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近沒什么比較好的思路,所以基本是想到什么寫什么。很多人有碰到過這樣的需求,展示一段文字,但是這段文字中間的幾個(gè)字顏色不同,比如這樣:

展示一段 這幾個(gè)字顏色不同\color{red}{這幾個(gè)字顏色不同}這幾個(gè)字顏色不同 的文字

只是其中有一段要換文字的樣式而已,其它的顯示正常。有的人實(shí)現(xiàn)這個(gè)功能就用3個(gè)TextView去實(shí)現(xiàn)的,其實(shí)這是不對(duì)的,

有一些開發(fā)經(jīng)驗(yàn)的就知道有個(gè)類是SpannableString,它能實(shí)現(xiàn)這個(gè)功能。

SpannableString的使用

為什么它能實(shí)現(xiàn)這個(gè)功能呢?其實(shí)你setTextView最終還是繪制出來,比如大家都知道Canvas是能繪制文字的,如果我用Canvas去繪制文字的話,我就很輕易能實(shí)現(xiàn)各種效果,包括上面的一段文字變色。其實(shí)SpannableString的效果就相當(dāng)于Canvas去繪制的效果一樣。

而spannableStringBuilder相對(duì)于SpannableString而言是多了拼接的效果,他們都一樣,所以我這里就以spannableStringBuilder來說,如果我要使用spannableStringBuilder去實(shí)現(xiàn)上面的效果,可以這樣寫

SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(“展示一段這幾個(gè)字顏色不同的文字”);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);
spannableStringBuilder.setSpan(foregroundColorSpan, 4, 11, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(spannableStringBuilder);

這樣就能實(shí)現(xiàn)上面的效果了,我們可以簡單看看ForegroundColorSpan,它有個(gè)updateDrawState方法

/**
 * Updates the color of the TextPaint to the foreground color.
 */
@Override
public void updateDrawState(@NonNull TextPaint textPaint) {
    textPaint.setColor(mColor);
}

TextPaint繼承Paint,能看出這是一個(gè)設(shè)置畫筆的動(dòng)作。而spannableStringBuilder的setSpan方法的第一個(gè)參數(shù)就是指Span,那讓我們來看看系統(tǒng)提供了哪些常見的Span(我這里就列舉幾個(gè)常用的)

  • ForegroundColorSpan:文本顏色
  • BackgroundColorSpan:背景顏色
  • AbsoluteSizeSpan:字體的大?。ń^對(duì)值)
  • RelativeSizeSpan:字體的大?。ㄏ鄬?duì)值,xx倍)
  • StyleSpan:字體的風(fēng)格
  • UnderlineSpan:下劃線
  • StrikethroughSpan:刪除線

除了這些之外還有RasterizerSpan、ImageSpan、TypefaceSpan等等,感興趣的可以去看官方文檔,我這就不介紹這么多了。

然后我們看setSpan的最后一個(gè)參數(shù)flags,一共有4種類型:

  • SPAN_EXCLUSIVE_EXCLUSIVE:包括前面,包括后面
  • SPAN_EXCLUSIVE_INCLUSIVE:包括前面,不包括后面
  • SPAN_INCLUSIVE_EXCLUSIVE:不包括前面,包括后面
  • SPAN_INCLUSIVE_INCLUSIVE:不包括前面,不包括后面

這是什么意思呢?看得出它的命名有兩個(gè)單詞_EXCLUSIVE_EXCLUSIVE這樣的,第一個(gè)表示影響范圍是前面,第二個(gè)表示影響范圍是后面。EXCLUSIVE表示包括,INCLUSIVE表示不包括。

假如我這句話“123456”,我設(shè)置2種樣式,123用ForegroundColorSpan設(shè)置字體為紅色,456用BackgroundColorSpan設(shè)置背景為紅色。假如123使用SPAN_EXCLUSIVE_EXCLUSIVE,456使用SPAN_INCLUSIVE_INCLUSIVE,那最終效果是123字體是紅色,456字體和背景都是紅色。

封裝SpannableString

簡單的介紹了SpannableString的作用和調(diào)用方式,我們來看看具體怎么使用,如果你按照上面的代碼,每設(shè)置一個(gè)文字效果,都要寫這么一串代碼,那最終看起來會(huì)很臃腫

SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(“展示一段這幾個(gè)字顏色不同的文字”);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);
spannableStringBuilder.setSpan(foregroundColorSpan, 4, 11, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(spannableStringBuilder);

所以我們可以封裝一下(把自己會(huì)用上的效果先整合起來)

public class SpanStringUtils {
    private Context context;
    private SpannableStringBuilder spannableStringBuilder;
    private int lp = 0;
    private int rp = 0;
    private List<Span> list = new ArrayList<>();
    public SpanStringUtils(Context context) {
        this.context = context;
        spannableStringBuilder = new SpannableStringBuilder();
    }
    public SpanStringUtils append(Span span) {
        list.add(span);
        return this;
    }
    public CharSequence create() {
        if (list == null || list.isEmpty()) {
            return null;
        }
        for (int i = 0; i < list.size(); i++) {
            Span span = list.get(i);
            createSpan(span);
        }
        return spannableStringBuilder;
    }
    private void createSpan(Span span) {
        if (span != null) {
            String str = span.textRId == -1 ? span.text : context.getString(span.textRId);
            rp = lp + str.length();
            spannableStringBuilder.append(str);
            if (span.spannable != null) {
                spannableStringBuilder.setSpan(span.spannable, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.textColor != -1) {
                ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(context.getResources().getColor(span.textColor));
                spannableStringBuilder.setSpan(foregroundColorSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.backgroundColor != -1) {
                BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(context.getResources().getColor(span.backgroundColor));
                spannableStringBuilder.setSpan(backgroundColorSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.relativeSize > 0) {
                RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(span.relativeSize);
                spannableStringBuilder.setSpan(relativeSizeSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.xSpan > 0) {
                ScaleXSpan scaleXSpan = new ScaleXSpan(span.xSpan);
                spannableStringBuilder.setSpan(scaleXSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.style != -1) {
                StyleSpan styleSpan = new StyleSpan(span.style);
                spannableStringBuilder.setSpan(styleSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.isUnderline) {
                UnderlineSpan underlineSpan = new UnderlineSpan();
                spannableStringBuilder.setSpan(underlineSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (span.isStrikethrough) {
                StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
                spannableStringBuilder.setSpan(strikethroughSpan, lp, rp, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            lp = rp;
        }
    }
    public static class Span {
        private String text;
        private int textRId = -1;
        private int textColor = -1;
        private int backgroundColor = -1;
        private float relativeSize;
        private float xSpan;
        private int style = -1;
        private boolean isUnderline;
        private boolean isStrikethrough;
        private ParcelableSpan spannable;
        public Span setText(String text) {
            this.text = text;
            return this;
        }
        public Span setText(int rId) {
            this.textRId = rId;
            return this;
        }
        public Span setTextColor(int textColor) {
            this.textColor = textColor;
            return this;
        }
        public Span setBackgroundColor(int backgroundColor) {
            this.backgroundColor = backgroundColor;
            return this;
        }
        public Span setRelativeSize(float relativeSize) {
            this.relativeSize = relativeSize;
            return this;
        }
        public Span setxSpan(float xSpan) {
            this.xSpan = xSpan;
            return this;
        }
        public Span setStyle(int style) {
            this.style = style;
            return this;
        }
        public Span setUnderline(boolean underline) {
            isUnderline = underline;
            return this;
        }
        public Span setStrikethrough(boolean strikethrough) {
            isStrikethrough = strikethrough;
            return this;
        }
        public Span setSpannable(ParcelableSpan spannable) {
            this.spannable = spannable;
            return this;
        }
    }
}

因?yàn)槭怯胘ava寫的,所以設(shè)置成一個(gè)鏈?zhǔn)秸{(diào)用的方式最終看起來會(huì)比較美觀。Span表示每一段文字的效果,lp和rp是指向每段文字的范圍,其它的地方應(yīng)該都能很容易看懂。

然后在使用的時(shí)候這樣調(diào)用

TextView testTv = findViewById(R.id.tv_test);
testTv.setTextColor(Color.parseColor("#ffffff"));
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.orange));
CharSequence charSequence = new SpanStringUtils(this)
        .append(new SpanStringUtils.Span().setText("abcde").setTextColor(R.color.blue))
        .append(new SpanStringUtils.Span().setText("qqqq").setBackgroundColor(R.color.blue))
        .append(new SpanStringUtils.Span().setText("ccc").setRelativeSize(1.5f))
        .append(new SpanStringUtils.Span().setText("dddddd"))
        .append(new SpanStringUtils.Span().setText("eee").setSpannable(foregroundColorSpan))
        .append(new SpanStringUtils.Span().setText("8s8s8s8s").setStyle(Typeface.BOLD))
        .append(new SpanStringUtils.Span().setText("kk").setUnderline(true))
        .append(new SpanStringUtils.Span().setText("M").setStrikethrough(true))
        .append(new SpanStringUtils.Span()
                .setText("LAST")
                .setTextColor(R.color.jh_orange)
                .setRelativeSize(3f)
                .setUnderline(true)
                .setStrikethrough(true))
        .create();
testTv.setText(charSequence);

前面的都是單個(gè)效果,dddddd是不設(shè)效果,最后一個(gè)是混合效果,來看看執(zhí)行的結(jié)果

最后說一下,kotlin的話,不需要這樣的方式,它能有更簡潔的封裝方式去實(shí)現(xiàn)這樣的效果,我這里就不過多介紹了。

更多關(guān)于Android設(shè)置TextView樣式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android編程鬧鐘設(shè)置方法詳解

    Android編程鬧鐘設(shè)置方法詳解

    這篇文章主要介紹了Android編程鬧鐘設(shè)置方法,結(jié)合實(shí)例形式分析了Android鬧鐘設(shè)置的步驟與時(shí)間監(jiān)聽的操作技巧,需要的朋友可以參考下
    2016-10-10
  • AsyncTask類實(shí)例詳解

    AsyncTask類實(shí)例詳解

    這篇文章主要介紹了AsyncTask類實(shí)例詳解
    2017-10-10
  • Repo工作原理和使用介紹

    Repo工作原理和使用介紹

    Repo是谷歌用Python腳本寫的調(diào)用git的一個(gè)腳本,可以實(shí)現(xiàn)管理多個(gè)git庫。本文詳細(xì)講解了Repo的工作原理和使用介紹,需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • Android TextView控件文字添加下劃線的實(shí)現(xiàn)方法

    Android TextView控件文字添加下劃線的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狝ndroid TextView控件文字添加下劃線的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09
  • Android Studio 新手入門教程(一)基本設(shè)置圖解

    Android Studio 新手入門教程(一)基本設(shè)置圖解

    這篇文章主要介紹了Android Studio 新手入門教程(一)基本設(shè)置圖解,需要的朋友可以參考下
    2017-12-12
  • Android實(shí)現(xiàn)閃屏歡迎界面

    Android實(shí)現(xiàn)閃屏歡迎界面

    這篇文章主要介紹了Android實(shí)現(xiàn)閃屏歡迎界面的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android RecycleView滑動(dòng)停止后自動(dòng)吸附效果的實(shí)現(xiàn)代碼(滑動(dòng)定位)

    Android RecycleView滑動(dòng)停止后自動(dòng)吸附效果的實(shí)現(xiàn)代碼(滑動(dòng)定位)

    這篇文章主要介紹了Android RecycleView滑動(dòng)停止后自動(dòng)吸附效果的實(shí)現(xiàn)代碼(滑動(dòng)定位),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Android中View繪制流程詳細(xì)介紹

    Android中View繪制流程詳細(xì)介紹

    這篇文章主要介紹了Android中View繪制流程詳細(xì)介紹,涉及創(chuàng)建ViewRoot并關(guān)聯(lián)View,ViewRoot等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • android實(shí)現(xiàn)輪播圖引導(dǎo)頁

    android實(shí)現(xiàn)輪播圖引導(dǎo)頁

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)輪播圖引導(dǎo)頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Input系統(tǒng)按鍵事件的分發(fā)處理示例詳解

    Input系統(tǒng)按鍵事件的分發(fā)處理示例詳解

    這篇文章主要為大家介紹了Input系統(tǒng)按鍵事件的分發(fā)處理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論