Android TextView部分文字有不同的颜色和部分文字点击事

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

有的人会采用不同的 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?

SpannableString,是CharSequence的一种,原本的CharSequence只是一串字符序列,没有任何样式,而SpannableString可以在字符序列基础上对指定的字符进行润饰,在开发中,TextView可以通过setText(CharSequence)传入SpannableString作为参数,来达到显示不同样式文字的效果。

创建方式

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

如何对SpannableString进行润饰?

一般通过以下方式进行设置

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模式。

ForegroundColorSpan

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

ForegroundColorSpan:前景色,也就是对文字上色,颜色设置为GREEN,start为4,end为7,应该是“陈奕迅”三个字显示为绿色。

BackgroudColorSpan

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

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

AbsoluteSizeSpan

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

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

UnderlineSpan (下划线)

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

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

StrikethroughSpan (中间删除线)

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

SuperscriptSpan (上标)

SpannableString spannableString = new SpannableString("如果我是陈奕迅");
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:设置文字为上标

部分文字的点击事件

spannableString.setSpan(new MyClickText(this), 4, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvValue3.setText(spannableString);
tvValue3.setMovementMethod(LinkMovementMethod.getInstance());
tvValue3.setHighlightColor(Color.BLUE); //设置点击后的颜色为透明

对于一个TextView 先必须要使用 TextView.setMovementMethod(LinkMovementMethod.getInstance());

给一个TextView设置这个属性有什么用呢? 其实就是给这个TextView实现超链接效果,不设置当然就没有点击事件了。

你需要写一个类来实现ClickableSpan 并且 .setSpan(继承ClickableSpan的类,对应效果的开始位置,对应效果的结束位置, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

下面是MyClickText的实现

private class MyClickText extends ClickableSpan{
    private Context context;
    public MyClickText(MainActivity mainActivity) {
        this.context = mainActivity;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        //设置文本的颜色
        ds.setColor(Color.RED);
        //超链接形式的下划线,false 表示不显示下划线,true表示显示下划线
        ds.setUnderlineText(false);
    }

    @Override
    public void onClick(View widget) {
       Toast.makeText(MainActivity.this,"发生了点击效果",Toast.LENGTH_SHORT).show();
    }
}

总结

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

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

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值