SpannableString&SpannableStringBuilder一些简单介绍

开始

最近还是挺忙的,改公司各种bug,添加新的功能,这不,有个新的功能如下:
这里写图片描述 上面的两个人昵称wuguang,rozbo是可以点击进入各自的用户信息界面的,刚开始第一感觉是使用Html.from(string)去做,后来发现颜色上是对了,就是点击事件不太好写,在前辈的教育下新解锁了SpannableString技能。

以前也用过SpannableString,但是没有深入的学习,现在发现有时间,就好好的看一下。先不说这玩意儿是干嘛的,其实我也听懵逼的,因为andorid这玩意东西太多了,那么就看功能,然后再慢慢说吧:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这就是一个TextView借助SpannableString实现的,就像Google官方文档介绍的一样:
This is the class for text whose content and markup can both be changed.
意思是内容和标记都可以更改的类。

SpannableString&SpannableStringBuilder

这两个类就像String与StringBuilder一样,一个内容是不可变的,一个是可变的(SpannableStringBuilder也是通过append进行拼接的)。SpannableString与SpannableStringBuilder都实现了CharSequence接口,所以他们都可以在TextView中直接使用。

SpannableString与SpannableStringBuilder的使用方法类似,最主要的方法算是:

 public void setSpan(Object what, int start, int end, int flags) {
        super.setSpan(what, start, end, flags);
    }

这里的what就是我们要实现的span,也就是我们需要的各种效果。start,end,flags等会再谈,先看android给我们提供的各种效果:
这里写图片描述
大致可以分为:
1.BackgroundColorSpan/ForegroundColorSpan: 背景/前景效果,类似于这种效果:
这里写图片描述
简单代码如下:

SpannableString ss = new SpannableString(msg);
BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.BLUE);
ss.setSpan(colorSpan,3,6, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
mTvView.setText(ss);

2.可点击的span:URLSpan与ClickableSpan,URLSpan是继承自ClickableSpan,实现了onClick方法,基本效果如下:
这里写图片描述
简单代码如下:

 SpannableString ss = new SpannableString(msg);
        ClickableSpan span = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, ">>>click me>>>", Toast.LENGTH_SHORT).show();
            }
        };
        ss.setSpan(span,0,5,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        mTvView.setText(ss);
        mTvView.setMovementMethod(LinkMovementMethod.getInstance());

3.改变字符大小,样式,排列型的span,包括以下几个:

a.

可更改字体的TypefaceSpan, 目前example里面可以选择的字体有:monospace”, “serif”, and “sans-serif”. 但是个人感觉不太明显,所以感觉没什么卵用。

b

.基于X轴缩放的span:
这里写图片描述
代码如下:

 SpannableString ss = new SpannableString(msg);
 //放大5.2倍
 ScaleXSpan xspan = new ScaleXSpan(5.2f);
 ss.setSpan(xspan,1,5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 mTvView.setText(ss);

既然有基于X轴缩放的,那有没有关于y轴缩放的呢?答案是没有啊,至于原因我表示也不清楚,大家自行脑补吧。

c.

RelativeSizeSpan&AbsouluteSizeSpan 相对大小与绝对大小。

//相对字体的1.5倍的大小
这里写图片描述

//绝对大小20dip的字体
这里写图片描述

d.

SuperscriptSpan&SubcriptSpan 应用于数字公式或者模型中的上下标:
这里写图片描述
大致代码为:

    String str = "(X1 + X2)2 = X12+X22+2X1X2" ;
        SpannableString ss = new SpannableString(str);

        //设置下标
        ss.setSpan(new SubscriptSpan(),2,3,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new SubscriptSpan(),7,8,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //设置上标
        ss.setSpan(new SuperscriptSpan(),9,10,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        ss.setSpan(new SubscriptSpan(),14,15,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new SuperscriptSpan(),15,16,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        ss.setSpan(new SubscriptSpan(),18,19,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new SuperscriptSpan(),19,20,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        ss.setSpan(new SubscriptSpan(),23,24,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new SubscriptSpan(),25,26,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        mTvView.setText(ss);

e.

StyleSpan&TextAppearanceSpan
前者可以控制字体是否粗体,是否斜体,是否bold_italic
后者则通过自己设置的R.style.my_style控制字体大小,颜色等样式
这里写图片描述

这里写图片描述

4.其他效果的span:

a.

MaskFilterSpan 修饰效果的span,andorid本身提供了两种效果:模糊和浮雕效果:
这里写图片描述

这里写图片描述
但是这里需要关闭硬件加速,否则看不出来效果,具体参数可以参考

5.UnderLineSpan&StrikethroughSpan 这个就不解释了,分别是我们的下划线span和删除线span:
这里写图片描述

这里写图片描述

关于flag参数

不管是SpannableString和SpannableStringBuilder,都是有个方法:

 public void setSpan(Object what, int start, int end, int flags) ;

其中最后一个参数,这个flags对SpannableString没有作用(亲测过),因为SpannableString像String一样,是不变的,没法改变内容,即使你传入0也无所谓。

但是对于SpannableStringBuilder就不一样了,它有个四个参数值:

 Spannable.SPAN_INCLUSIVE_INCLUSIVE
 Spannable.SPAN_INCLUSIVE_EXCLUSIVE ;
 Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;

我么大概知道,INCLUSIVE是包含的意思,而EXCLUSIVE就是不包含的意思,那么上面的就可以非常简单的理解为数学中是否包含了:

[A,B];  //左右都包含
[A,B);  //左包含 右不包含
(A,B];  //左不包含,右包含
(A,B);  //左右都不包含

而这里的A,B就是我们setSpan中的start和end参数了。具体什么意思,我们来举个例子:
这里写图片描述
我们在start=3,end=8的地方设置了下划线span,模式为Spanned.SPAN_EXCLUSIVE_EXCLUSIVE【也就是两边都不包括】,代码如下:

        mTv = (TextView) findViewById(R.id.id_tv);
        mSpannableBuilder = new SpannableStringBuilder("1234567890张三Tom");
        UnderlineSpan span = new UnderlineSpan();
        mSpannableBuilder.setSpan(span,3,8,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTv.setText(mSpannableBuilder);

现在在index=3处插入数据:

mSpannableBuilder.insert(3,"hello");
mTv.setText(mSpannableBuilder);

我们看到是这样的:
这里写图片描述
我们可以看到我们的hello没有应用到下划线的。

现在把flag换成SPAN_INCLUSIVE_INCLUSIVE试一下

mSpannableBuilder = new SpannableStringBuilder("1234567890张三Tom");
        UnderlineSpan span = new UnderlineSpan();
        mSpannableBuilder.setSpan(span,3,8,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        mTv.setText(mSpannableBuilder);

还是在index=3的地方插入:

mSpannableBuilder.insert(3,"hello");
mTv.setText(mSpannableBuilder);

这里写图片描述
我们看到了hello也被添加了下划线。

那么这个flag就表明了在start和end区间里,span的应用情况。如果insert的index在这个区间内,那么插入的数据也会被应用到该sapn效果中了。

基本上就是这里了。改洗洗睡了。

代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值