4

同じ Span オブジェクトを使用して setSpan を 2 回超えることができないのはなぜですか?

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);
    //  }

これをどのように説明できますか?

4

2 に答える 2

10

HashMapスパン オブジェクトは、表現内で , のキーとして巻き上げられるのではないかと思いますSpanned。したがって、同じスパン オブジェクトを再利用すると、以前の使用を新しい使用に置き換える効果があります。

于 2012-10-29T09:49:11.863 に答える
4

最近 Spannableのソース コードを読んで、Google でこの質問を見つけたので、この質問に答えるソース コードをいくつか貼り付けたいと思います。

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 メソッドで同じスパンを渡すと、スパン配列が同じかどうかをチェックし、古い開始値と終了値をニュースに置き換えます。

于 2016-11-23T04:33:49.850 に答える