TextView 局部文本樣式設置之二:SpannableString

上次寫了《TextView 局部文本樣式設置》後,一直想整理一篇關於 SpannableString 的文章,但是一懶就忘記了,剛好最近項目中局部文字樣式修改用得多,所以就趁空把文章整理出來,這是參考其他文章整理出來的,以便後續查看。
以下尺寸工具類採用《常用代碼整理:尺寸工具類(SizeUtil)

1、常用樣式

SpannableString spannableString1 = new SpannableString("這是自帶騷氣的文本,哈1哈2哈3");
// 設置字體大小,單位爲像素
spannableString1.setSpan(new AbsoluteSizeSpan(20), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置字體大小,第二個參數表示前面的字體大小單位爲是否爲dip
spannableString1.setSpan(new AbsoluteSizeSpan(20, true), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//設置字體大小,參數表示爲默認字體大小的多少倍(如果開發者在xml中設置了android:textSize,就採用開發者設置的大小)
spannableString1.setSpan(new RelativeSizeSpan(2.5f), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置字體樣式: NORMAL正常,BOLD粗體,ITALIC斜體,BOLD_ITALIC粗斜體
spannableString1.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置字體前景色(字體顏色)
spannableString1.setSpan(new ForegroundColorSpan(Color.RED), 7, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置下劃線
spannableString1.setSpan(new UnderlineSpan(), 9, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置刪除線
spannableString1.setSpan(new StrikethroughSpan(), 10, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設置上下標
spannableString1.setSpan(new SubscriptSpan(), 13, 14, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString1.setSpan(new SuperscriptSpan(), 15, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvOne.setText(spannableString1);

2、圖片替換

SpannableString spannableString2 = new SpannableString("再來看看騷氣的圖片替換");
Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
spannableString2.setSpan(new ImageSpan(drawable), 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvTwo.setText(spannableString2);

3、繪製背景

SpannableString spannableString3 = new SpannableString("這是騷氣的指定文字背景繪製");
spannableString3.setSpan(new BackgroundSpan(this, 0xffff0000), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTvThree.setText(spannableString3);
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.style.ReplacementSpan;

public class BackgroundSpan extends ReplacementSpan {
    private Context mContext;
    private int mTextColor;
    private int mHeight, mTextSize, mRadius, mTextPadding, mMargin;
    private RectF mTempF = new RectF();

    public BackgroundSpan(Context context, int textColor) {
        super();
        this.mContext = context;
        this.mTextColor = textColor;
        this.mTextSize = SizeUtil.sp2px(mContext, 10);
        this.mRadius = SizeUtil.dip2px(mContext, 3);
        this.mHeight = SizeUtil.dip2px(mContext, 13);
        this.mTextPadding = SizeUtil.dip2px(mContext, 2.5f);
        this.mMargin = SizeUtil.dip2px(mContext, 5f);
    }

    /**
     * 設置寬度
     * 返回值就是Span替換文字後所佔的寬度
     */
    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        // 這裏要設定文本的文字大小,不然系統會採用xml中開發者設置的android:textSize(開發者沒設置就是textview的默認textSize)
        // 且要注意getSize方法快於draw方法被調用
        paint.setTextSize(mTextSize);
        return ((int) paint.measureText(text, start, end)) + mTextPadding * 2 + SizeUtil.dip2px(mContext, 3);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        paint.setAntiAlias(true); // 抗鋸齒
        paint.setDither(true); // 防抖動

        // 設置畫筆,繪製背景
        // paint.setColor(mTextColor);
        // paint.setStyle(Paint.Style.STROKE);
        paint.setColor(0xff00ff00);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        /*
        Paint.Style.FILL:填充內部
        Paint.Style.FILL_AND_STROKE  :填充內部和描邊
        Paint.Style.STROKE  :描邊
        */
        mTempF.set(x, top + mMargin, x + ((int) paint.measureText(text, start, end)) + mTextPadding * 2, top + mMargin + mHeight);
        canvas.drawRoundRect(mTempF, mRadius, mRadius, paint);
        /*
        public void drawRoundRect (RectF rect, float rx, float ry, Paint paint)
        rect:RectF對象,set(float left, float top, float right, float bottom)
        rx:x方向上的圓角半徑
        ry:y方向上的圓角半徑
        paint:繪製時所用畫筆
        */

        // 設置畫筆,繪製文字
        paint.setColor(mTextColor);
        paint.setTextSize(mTextSize);
        float textY = top + mMargin + mHeight / 2 - (paint.descent() + paint.ascent()) / 2;
        canvas.drawText(text, start, end, x + mTextPadding, textY, paint);
        /*
        drawText(CharSequence text, int start, int end, float x, float y, Paint paint)
        x:繪製文本的起始x座標
        y:繪製文本的起始y座標
        */
    }
}


參考文章:
1、https://blog.csdn.net/freak_csh/article/details/79276945
2、https://blog.csdn.net/u012735483/article/details/52902047

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