Why can't I use the same Span to install twice twice?

Why can't I use the same Span to install twice twice?

SpannableString ss = new SpannableString ("aaaaa [1] bbbb [1] cccc [1]");

I need to replace all [1] with the image. If I use the following code, only the latter is replaced by an image:

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

If you change the following code, all [1] are replaced by the image.

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

How to explain this?

+4
source share
2 answers

I suspect that span objects terminate as HashMap keys, inside the Spanned . Consequently, reusing the same span will replace its previous use with a new use.

+6
source

I read the Spannable source code and found this question from Google, so I want to paste some source code to answer this question.

The SpannableString SpannableStringInternal implementation and the setSpan method are as follows.

 /* 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; } } ... } 

When you pass the same range using the setSpan method, it will check if the array of spaces has the same number and replaces the old start and end value with news.

+2
source

Source: https://habr.com/ru/post/1442694/


All Articles