美文网首页Android技术知识AndroidAndroid面试必备(基本知识)
Android 中 TextView 部分文字有不同的颜色和部分

Android 中 TextView 部分文字有不同的颜色和部分

作者: i小灰 | 来源:发表于2020-12-04 11:17 被阅读0次

    一、前言:

    我们在开发中,经常遇到一段文本,需要单独给它部分文字设置不同的样式,有的文字设置为粗体,有的文字设置特殊的颜色,有的地方要加入表情,遇到数学公式还可能要设置上下标,这时候该怎么办呢?

    有的人会采用不同的 TextView,这样就可以完美解决了。先不说这个方法行不行得通,事实上,若采用这种方式,当碰上一段文字需要设置非常多的样式时,光是这一堆TextView就够浪费资源的了,布局还复杂,也不利于维护,因此这种方式一般不会被采用。

    那么有其他办法吗?有,并且还很简单,今天介绍的这个SpannableString就是用来解决这个问题的。

    xml 代码片段:

         <TextView
            android:id="@+id/tv_value"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="要变色的值"
            />
    
    

    第一种方法:

            //方法一:
            TextView tvValue = findViewById(R.id.tv_value);
            String str="默认颜色<font color='#FF0000'><small>红颜色 
           </small></font>";
            tvValue.setTextSize(18);
            tvValue.setText(Html.fromHtml(str));
    
    

    第二种方法:
    采用 SpannableString实现

    二、 SpannableString使用:

    1、SpannableString、SpannableStringBuilder与String的关系

    首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉,等等。所以,总而言之,SpannableString、SpannableStringBuilder与String一样, 首先也是传字符串,但SpannableString、SpannableStringBuilder可以对这些字符串添加额外的样式信息,但String则不行。

    注意:如果这些额外信息能被所用的方式支持,比如将SpannableString传给TextView;也有对这些额外信息不支持的,比如前一章讲到的Canvas绘制文字,对于不支持的情况,SpannableString和SpannableStringBuilder就是退化为String类型,直接显示原来的String字符串,而不会再显示这些附加的额外信息。

    2、SpannableString与SpannableStringBuilder区别

    它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String;

    image

    3、创建方式

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    
    

    设置

    spannableString.setSpan(Object what, int start, int end, int flags);
    
    

    这里讲解一下几个参数的意义:

    • what:对SpannableString进行润色的各种Span;
    • int:需要润色文字段开始的下标;
    • end:需要润色文字段结束的下标;
    • flags:决定开始和结束下标是否包含的标志位,有四个参数可选
    1. SPAN_INCLUSIVE_EXCLUSIVE:包括开始下标,但不包括结束下标
    2. SPAN_EXCLUSIVE_INCLUSIVE:不包括开始下标,但包括结束下标
    3. SPAN_INCLUSIVE_INCLUSIVE:既包括开始下标,又包括结束下标
    4. SPAN_EXCLUSIVE_EXCLUSIVE:不包括开始下标,也不包括结束下标

    这里涉及到一个重要的角色,就是各种各样的span,它决定我们要对文字的进行怎样的润饰,而后三个参数决定润饰哪些文字,为了方便起见,后面的flags默认都使用SPAN_INCLUSIVE_EXCLUSIVE模式。

    3、 ForegroundColorSpan

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    ForegroundColorSpan foregroundColorSpan1 = new ForegroundColorSpan(Color.GREEN);
    ForegroundColorSpan foregroundColorSpan2 = new ForegroundColorSpan(Color.GREEN);
    spannableString.setSpan(foregroundColorSpan1, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(foregroundColorSpan2, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    
    • ForegroundColorSpan:前景色,也就是对文字上色,颜色设置为GREEN,start为4,end为7,应该是“陈奕迅”三个字显示为绿色。
    • “如果” 也是绿色
      注意:必须new两个ForegroundColorSpan,否则只有一个地方字体变绿

    4、 BackgroudColorSpan

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);
    spannableString.setSpan(backgroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    

    BackgroudColorSpan:与ForegroundColorSpan类似,对文字背景上色

    5、 AbsoluteSizeSpan

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(40, true);
    spannableString.setSpan(absoluteSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    

    AbsoluteSizeSpan:设置字体的相绝对大小,40表示文字大小,true表示单位为dip,若为false则表示px

    6、 UnderlineSpan (下划线)

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    UnderlineSpan underlineSpan = new UnderlineSpan();
    spannableString.setSpan(underlineSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    

    UnderlineSpan:设置文字下划线,强调突出文字时可以使用该span

    7、StrikethroughSpan (中间删除线)

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
    spannableString.setSpan(strikethroughSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    

    8、 SuperscriptSpan (上标)

    代码

    SpannableStringBuilder spannableString = new SpannableStringBuilder("如果我是陈奕迅");
    SuperscriptSpan superscriptSpan = new SuperscriptSpan();
    RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(0.8f);
    spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(superscriptSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
    
    

    SuperscriptSpan:设置文字为上标

    9、部分文字的点击事件

    效果图:

    image
            TextView tv1 = view.findViewById(R.id.tv1);
            String content = " 欢迎来到SumanSoul为了更好地向用户提供服务,未经用户同意,SumanSoul不会自动收集、获取、共享或对外提供用户个人信息;你可以随时查看、更正或删除你的个人信息,SumanSoul也提供用户注销功能。";
            tv_content.setText(content.replace(" ", ""));
            SpannableStringBuilder spannableString = new SpannableStringBuilder("点击查看完整「用户协议」和「隐私政策」");
            spannableString.setSpan(new TextAgreementClick(), 6, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spannableString.setSpan(new TextPrivacyClick(), 13, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            //设置点击事件,加上这句话才有效果
            tv1.setMovementMethod(LinkMovementMethod.getInstance());
             //设置点击后的颜色为透明(有默认背景)
           tv1.setHighlightColor(BaseApplication.getInstance().getResources().getColor(R.color.transparent));
            tv1.setText(spannableString);
    
    
      <!-- 透明背景色-->
        <color name="transparent" tools:ignore="MissingDefaultResource">#00000000</color>
    
    

    下面是TextAgreementClick实现ClickableSpan

        private class TextAgreementClick extends ClickableSpan{
    
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                //设置文本的颜色
                ds.setColor(Color.RED);
                //超链接形式的下划线,false 表示不显示下划线,true表示显示下划线
                ds.setUnderlineText(false);
            }
    
            @Override
            public void onClick(View widget) {
               // 执行点击逻辑
            }
        }
    
    

    三、总结

    • ForegroundColorSpan:前景色
    • BackgroundColorSpan:背景色
    • ClickableSpan:抽象类,可点击效果,重写onClick方法响应点击事件
    • URLSpan:超链接
    • MaskFilterSpan:EmbossMaskFilter浮雕效果,BlurMaskFilter模糊效果
    • RelativeSpan:文字相对大小
    • AbsoluteSpan:文字绝对大小
    • ScaleXSpan:x轴缩放
    • styleSpan:文字样式
    • TypefaceSpan:文字字体类型
    • TextApearanceSpan:文字外貌
    • UnderlineSpan:下划线
    • StrikeThroughSpan:删除线
    • SuperscriptSpan:上标
    • SubscriptSpan:下标
    • ImageSpan:图片

    这些Span能够很好地帮助我们润色文字,以非常简单地方式获得复杂和绚丽的文字效果,着实是开发中的一大利器,喜欢的朋友收藏备用吧。

    相关文章

      网友评论

        本文标题:Android 中 TextView 部分文字有不同的颜色和部分

        本文链接:https://www.haomeiwen.com/subject/cunoiktx.html