解释Span标志的含义,如SPAN_EXCLUSIVE_EXCLUSIVE
有人可以清楚地解释什么样的SPAN_EXCLUSIVE_EXCLUSIVE
和SPAN_MARK_MARK
这些跨度标志是什么意思,什么时候使用什么标志?
我不明白的官方文件,当它说:
SPAN_EXCLUSIVE_EXCLUSIVE
types的SPAN_EXCLUSIVE_EXCLUSIVE
不会扩展为包含在起点或终点处插入的文本。
“扩展到包含”是指插入跨度后所做的编辑?
这是否意味着这些标志不会影响具有不可变文本的Spannables?
“扩展到包含”是指插入跨度后所做的编辑?
是。 例如,假设我们有以下几点:
狐狸跳了起来。
如果我们对粗体字跨度使用了SPAN_EXCLUSIVE_EXCLUSIVE
,并且在跨度中间插入文本,则仍然是粗体:
快速的棕色狐狸跳了起来。
但是,如果我们在粗体字的开头或结尾插入文本,插入的文本不是粗体:
真狐狸跳了起来。
但是,如果我们使用了SPAN_INCLUSIVE_EXCLUSIVE
,那么在开始处插入文本将作为跨度的一部分包含在内,我们将会:
真狐狸跳了起来。
这是否意味着这些标志不会影响具有不可变文本的Spannables?
我会说,他们用于不可变的文本有限。 大多数情况下,这些将与SpannableStringBuilder
一起使用或者在封面下使用的东西(例如EditText
)。
旗帜并不意味着什么
当我第一次看到Spannable
标志的Spannable
和EXCLUSIVE
部分时,我想他们只是告诉了span是否包含span的开始和结束索引位置。 这不是真的。 让我用下面的例子来说明。
String myString = "01234"; int start = 1; int end = 3; int spanFlag = Spannable.SPAN_INCLUSIVE_INCLUSIVE; // this is what is changing SpannableString spannableString = new SpannableString(myString); ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED); spannableString.setSpan(foregroundSpan, start, end, spanFlag); textView.setText(spannableString);
结果如下:
SPAN_INCLUSIVE_INCLUSIVE
SPAN_INCLUSIVE_EXCLUSIVE
SPAN_EXCLUSIVE_INCLUSIVE
SPAN_EXCLUSIVE_EXCLUSIVE
他们都是一样的! 标志不影响跨度。 跨度始终包含起始索引处的字符,并排除末尾索引处的字符。
旗帜真的意味着什么
Spannable标志的INCLUSIVE和EXCLUSIVE
部分实际上表明该跨度是否应包含插入到开始或结束位置的文本 。
这是一个修改的例子来说明这一点。
String myString = "01234"; int start = 1; int end = 3; int spanFlag = Spannable.SPAN_INCLUSIVE_INCLUSIVE; // this is what is changing // set the span SpannableStringBuilder spannableString = new SpannableStringBuilder(myString); ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED); spannableString.setSpan(foregroundSpan, start, end, spanFlag); // insert the text after the span has already been set // (inserting at start index second so that end index doesn't get messed up) spannableString.insert(end, "x"); spannableString.insert(start, "x"); textView.setText(spannableString);
以下是在结尾处插入x
并开始索引后的结果:
SPAN_INCLUSIVE_INCLUSIVE
SPAN_INCLUSIVE_EXCLUSIVE
SPAN_EXCLUSIVE_INCLUSIVE
SPAN_EXCLUSIVE_EXCLUSIVE
笔记
- 这个答案大部分描述了OP已经知道的事情。 我只是把它添加到像我这样不了解这些东西的未来访问者。
- 在第二个例子中,我必须使用
SpannableStringBuilder
因为SpannableStringBuilder
的文本是不可变的,所以你不能插入文本。 因此,标志对于SpannableString
通常是没有意义的。 但是,可以想象一种情况,SpannableString
的跨度复制到SpannableStringBuilder
或Editable
,并从那里开始标记。 - 请参阅
SpannableString
,SpannableStringBuilder
,Editable
之间的区别。