SpannableString Spanned 四种flag真正的含义


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

参数1 what:    各种Span 比如字体大小、字体颜色等

参数2 start :    所要修改字符下标开始位置,修改会包含start这个位置

参数2 end :     所要修改字符下标结束位置,不包含该位置字符

参数2 flags:     一般有四个常用模式,下面会提,这个flag和前两个参数start和end没有任何关系,就是它

                        不是用来控制前两个参数的

下面就说几个经常搞不清的情况

1 start 和 end 问题

当你操作TextView的时候,无论你把flags参数设置为哪种模式,都不会影响 start 和 end,字符改变的位置包含start位置不包含end位置

如图: start:1 ; end:6 .   图中字符下标 [1]-[5]的字符字体变大 ,无论flags是什么都不会影响变大字体的位置

图中字符串长度为10 下标对应  [0]-[9]

如图 start:1 ; end:10   图中字符下标 [1]-[9]的字符字体变大

但是如果你end 输入11,程序就会崩溃,直接出现异常。10也超出这个字符的下标了为啥10就不会出错呢?

看源码:

 

/* package */ void setSpan(Object what, int start, int end, int flags) {
    int nstart = start;
    int nend = end;

    checkRange("setSpan", start, end);//①:检查 start和end是否符合要求

    if ((flags & Spannable.SPAN_PARAGRAPH) == Spannable.SPAN_PARAGRAPH) {
        if (start != 0 && start != length()) {
            char c = charAt(start - 1);

            if (c != '\n')
                throw new RuntimeException(
                        "PARAGRAPH span must start at paragraph boundary" +
                        " (" + start + " follows " + c + ")");
        }

        if (end != 0 && end != length()) {
            char c = charAt(end - 1);//②:看到这个就明白为啥不包含end了

            if (c != '\n')
                throw new RuntimeException(
                        "PARAGRAPH span must end at paragraph boundary" +
                        " (" + end + " follows " + c + ")");
        }
    }

checkRange(.....) 方法是什么样的?

 

private void checkRange(final String operation, int start, int end) {
    if (end < start) {
        throw new IndexOutOfBoundsException(operation + " " +
                                            region(start, end) +
                                            " has end before start");
    }

    int len = length();//这个length就是所要操作的字符串长度,就不贴源码了

    //通过比较end是否已超过字符串长度,若超过则抛出异常。
    // 因为上方② 处会charAt(end - 1)
    if (start > len || end > len) {
        throw new IndexOutOfBoundsException(operation + " " +
                                            region(start, end) +
                                            " ends beyond length " + len);
    }

    if (start < 0 || end < 0) {
        throw new IndexOutOfBoundsException(operation + " " +
                                            region(start, end) +
                                            " starts before 0");
    }
}

2 flags到底是干什么用的,什么时候会起作用呢?

当你不是操作TextView而是EditText这种可以输入的文本的时候,flags就起作用了。

你已经将某段字符做出改变,而你在所改变内容前后输入新的内容时,就会根据flags有所变化。

直接放图 看了就更容易明白:

1 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前后都不包含

图中字母a是改变字体大小后输入的,SPAN_EXCLUSIVE_EXCLUSIVE模式,大小不会发生改变。

Spanned.SPAN_EXCLUSIVE_INCLUSIVE 不包含前面 包含后面

如图 在改变字体大小后输入A, 前面A没有变大,后面的变大

 

3 Spanned.SPAN_INCLUSIVE_EXCLUSIVE 包含前面,不包含后面

4 Spanned.SPAN_INCLUSIVE_INCLUSIVE 前后都包含

总结一下,flags是对可以输入新文本的控件才会起作用,如果你是对TextView操作,flags用哪个都一样的。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值