【TextView分段显示不同颜色的字体——基础篇】

本文详细介绍如何使用Android的TextView进行字体颜色、背景颜色、大小、删除线、下划线及图标显示等样式的定制,包括使用SpannableString和HTML解析方法,并提供自定义ImageSpan和点击事件的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【TextView分段显示不同颜色的字体——进阶篇】封装

废话不多说,先上效果图
在这里插入图片描述
相应代码:

安卓自带的解析HTML:

 val strHtmlContent1 =
            "1.分段显示不同颜色<font color='#FF7200'>通过解析HTML来实现</font>" + "关键方法:Html.fromHtml";
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            tv01.setText(
                Html.fromHtml(
                    strHtmlContent1,
                    HtmlCompat.FROM_HTML_MODE_LEGACY
                )
            )
        } else {
            tv01.setText(Html.fromHtml(strHtmlContent1))
        }

        val strHtmlContent2 =
            "<img src='" + R.mipmap.ic_huo_yan + "'>" + " " + getString(R.string.html2);

        tv011.setText(Html.fromHtml(strHtmlContent2, object : Html.ImageGetter {
            override fun getDrawable(source: String?): Drawable {
                val id = Integer.parseInt(source!!)
                val drawable = ContextCompat.getDrawable(this@MainActivity, id);
                drawable!!.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
                return drawable
            }

        }, null))

第三方框架解析HTML,很不错:

  html_text.setHtml(
            "<h2>Hello wold</h2>" + "<ul><li>cats</li><li>dogs</li></ul>" + "<img src=\"ic_huo_yan\"/>", HtmlResImageGetter(this@MainActivity));

安卓原生的方法:

   //字体颜色
        val strContent2 = tv02.text.toString();
        val spannableString2 = SpannableString(strContent2);
        val mForegroundColorSpan = ForegroundColorSpan(Color.GREEN);
        spannableString2.setSpan(mForegroundColorSpan, 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv02.text = spannableString2;


        //字体背景颜色
        val strContent3 = tv03.text.toString();
        val spannableString3 = SpannableString(strContent3);
        val mBackgroundColorSpan = BackgroundColorSpan(Color.RED);
        spannableString3.setSpan(mBackgroundColorSpan, 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv03.text = spannableString3;


        //字体大小
        val strContent4 = tv04.text.toString();
        val spannableString4 = SpannableString(strContent4);
        val mAbsoluteSizeSpan = AbsoluteSizeSpan(11, true);
        spannableString4.setSpan(mAbsoluteSizeSpan, 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv04.text = spannableString4;


        //相对的字体大小,就是字体大小的多少倍
        val strContent5 = tv05.text.toString();
        val spannableString5 = SpannableString(strContent5);
        val mRelativeSizeSpan = RelativeSizeSpan(1.5f);
        spannableString5.setSpan(mRelativeSizeSpan, 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv05.text = spannableString5;

        //删除线
        val strContent6 = tv06.text.toString();
        val spannableString6 = SpannableString(strContent6);
        val mStrikethroughSpan = StrikethroughSpan();
        spannableString6.setSpan(mStrikethroughSpan, 2, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv06.text = spannableString6;

        //下划线
        val strContent7 = tv07.text.toString();
        val spannableString7 = SpannableString(strContent7);
        val mUnderlineSpan = UnderlineSpan();
        spannableString7.setSpan(mUnderlineSpan, 2, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv07.text = spannableString7;

        //显示图标,受行间距的影响
        val strContent8 = tv08.text.toString();
        val spannableString8 = SpannableString("  $strContent8");
        val mImageSpan = ImageSpan(this, R.mipmap.ic_huo_yan);
        spannableString8.setSpan(mImageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv08.text = spannableString8;

        //显示图标,不受行间距的影响
        val strContent9 = tv09.text.toString();
        val spannableString9 = SpannableString("  $strContent9");
        val mCenteredImageSpan = CenteredImageSpan(this, R.mipmap.ic_huo_yan);
        spannableString9.setSpan(mCenteredImageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv09.text = spannableString9;

        //点击事件
        val strContent10 = tv10.text.toString();
        val spannableString10 = SpannableString(strContent10);
        val clickableSpan = object : YpkClickableSpan() {
            override fun onClick(widget: View) {
                Toast.makeText(application, "ClickableSpan", Toast.LENGTH_LONG).show();
            }
        }
        spannableString10.setSpan(clickableSpan, 2, 13, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        tv10.movementMethod = LinkMovementMethod.getInstance()
        tv10.text = spannableString10;

        //效果叠加
        val strContent11 = tv11.text.toString();
        val spannableString11 = SpannableStringBuilder(strContent11);
        val mForegroundColorSpan11 = ForegroundColorSpan(Color.GREEN);
        spannableString11.setSpan(mForegroundColorSpan11, 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        val mAbsoluteSizeSpan12 = AbsoluteSizeSpan(11, true);
        spannableString11.setSpan(mAbsoluteSizeSpan12, 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv11.text = spannableString11;

自定义ImageSpan CenteredImageSpan

/**
 * ypk
 * 自定义 TextView 的ImageSpan
 * 能解决text中图标居中对齐问题(无论TextView是否设置行距)
 */
public class CenteredImageSpan extends ImageSpan {

    private int drawableSize, drawableWidth, drawableHeight;

    public CenteredImageSpan(Context context, final int drawableRes) {
        super(context, drawableRes);
    }


    public CenteredImageSpan(Context context, final int drawableRes, int drawableSize) {
        super(context, drawableRes);
        this.drawableSize = drawableSize;
    }

    public CenteredImageSpan(Context context, final int drawableRes, int drawableWidth, int drawableHeight) {
        super(context, drawableRes);
        this.drawableWidth = drawableWidth;
        this.drawableHeight = drawableHeight;
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
        // image to draw
        Drawable b = getDrawable();
        //这是drawable的宽和高
        if (drawableSize != 0) {
            b.setBounds(0, 0, drawableSize, drawableSize);
        } else if (drawableWidth != 0 && drawableHeight != 0) {
            b.setBounds(0, 0, drawableWidth, drawableHeight);
        }


        // font metrics of text to be replaced
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;

        canvas.save();
        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }
}

YpkClickableSpan

public class YpkClickableSpan extends ClickableSpan {


    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
       // super.updateDrawState(ds);
        ds.setColor(Color.BLUE);
        ds.setUnderlineText(false);
    }

    @Override
    public void onClick(@NonNull View widget) {

    }
}


相关博客:
html-textview

Android中SpannableString使用(二)

Android之TextView的样式类Span的使用详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值