2012-10-29 22 views
4

为什么不能使用相同的Span对象将Span设置为两次以上? SpannableString ss = new SpannableString(“aaaaa [1] bbbb [1] cccc [1]”);以及其他数据。为什么不能使用相同的Span对象来设置跨度两次?

我需要用图像替换所有的[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); 
    // } 

如何解释这一点?

回答

6

我怀疑跨度对象是HashMap的关键字,在Spanned表示中。因此,重复使用相同的跨度对象具有将其以前的使用替换为新用途的效果。

2

我近日阅读Spannable源代码,并通过Google找到此问题,因此我想粘贴一些源代码来回答此问题。

SpannableString由SpannableStringInternal和setSpan方法实现如下。

/* 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方法传递同一时期内,它会检查是否跨阵列具有相同的一个,并通过新闻取代旧的开始和结束的值。

相关问题