2012-10-29 25 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方法傳遞同一時期內,它會檢查是否跨陣列具有相同的一個,並通過新聞取代舊的開始和結束的值。

相關問題