为什么不能将相同的Span对象用于上面的setSpan两次?
SpannableString ss = new SpannableString(“aaaaa [1] bbbb [1] cccc [1]”);
我需要用图像替换所有[1]。如果我使用以下代码,则只有最后一个代码替换为图像:
etShow = (EditText) findViewById(R.id.show);
SpannableString ss = new SpannableString("aaaaa[1]bbbb[1]cccc[1]");
int[] starts = new int[3];
int[] ends = new int[3];
int h = 0;
int k = 0;
for (int i = 0; i < ss.length(); i++) {
if (ss.charAt(i) == '[') {
starts[h] = i;
h++;
} else if (ss.charAt(i) == ']') {
ends[k] = i;
k++;
}
}
Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
d.setBounds(0, 0, 50, 50);
ImageSpan im = new ImageSpan(d);
for(int i=0;i<3;i++){
ss.setSpan(im, starts[i], ends[i]+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
etShow.getText().insert(0, ss);
如果更改为以下代码,则所有[1]都将替换为图像。
Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
d.setBounds(0, 0, 50, 50);
ImageSpan im = new ImageSpan(d);
ImageSpan im1 = new ImageSpan(d);
ImageSpan im2 = new ImageSpan(d);
//for(int i=0;i<3;i++){
// ss.setSpan(im, starts[i], ends[i]+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
ss.setSpan(im, starts[0], ends[0]+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
ss.setSpan(im1, starts[1], ends[1]+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
ss.setSpan(im2, starts[2], ends[2]+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
// }
如何解释这个?
答案 0 :(得分:9)
我怀疑在HashMap
表示中,span对象最终成为Spanned
的键。因此,重用相同的span对象具有将其先前使用替换为新用途的效果。
答案 1 :(得分:4)
我现在阅读了Spannable源代码,并且谷歌发现了这个问题,所以我想粘贴一些源代码来回答这个问题。
SpannableStringInternal和setSpan方法实现的SpannableString如下所示。
/* package */ void setSpan(Object what, int start, int end, int flags) {
...
int count = mSpanCount;
Object[] spans = mSpans;
int[] data = mSpanData;
for (int i = 0; i < count; i++) {
if (spans[i] == what) {
int ostart = data[i * COLUMNS + START];
int oend = data[i * COLUMNS + END];
data[i * COLUMNS + START] = start;
data[i * COLUMNS + END] = end;
data[i * COLUMNS + FLAGS] = flags;
sendSpanChanged(what, ostart, oend, nstart, nend);
return;
}
}
...
}
当你通过setSpan方法传递相同的span时,它将检查spans数组是否具有相同的span并用新闻替换旧的start和end值。