user7232539
user7232539

Reputation:

Setting "same" styles to several parts of text

I have styles (e.g., BackgroundColorSpan) and I'd like to set it to multiple parts of the texts. But if the same instance of BackgroundColorSpan, etc. is assigned to other part of the text, the style moves.

E.g.,

  Object HighlightStyle = new BackgroundColorSpan(Color.argb(255, 255, 215, 0));
  TextView X = (TextView) findViewById(R.id.Text);
  SpannableStringBuilder SpannableBuilder = new SpannableStringBuilder();
  SpannableBuilder.append("1");
  SpannableBuilder.setSpan(HighlightStyle, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // This is hilited
  SpannableBuilder.append("2");
  SpannableBuilder.setSpan(HighlightStyle, 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // This is hilited and 1 is no more hilited
  SpannableBuilder.append("3");
  SpannableBuilder.append("4");
  SpannableBuilder.setSpan(HighlightStyle, 3, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // This is hilited and 1 and 2 are no more hilited
  X.setText(SpannableBuilder);
  // I want hilited 1,2,4 all at the same time

Why I do it ? A user can search for some text and that text should be highlighted.

How I'd like to do it ? All text is in a single TextView. I have a single SpannableStringBuilder. I have a method that breaks the text into parts - String and Boolean. String is part, Boolean says whether the text is matched - should be highligted - or not. I just pass, e.g., instance of BackgroundColorSpan into that method and it should be applied to every part that was matched but because of the behavior of setSpan, only last part is highlighted.

Potential solutions: Style doesn't implement .clone method. I could make a workaround like serialize/deserialize it to create new instances but that seems really like a hack.

Is there some elegant way how to set the same style to X parts of the text ?

Upvotes: 1

Views: 44

Answers (1)

Denysole
Denysole

Reputation: 4051

You should create new HighlightStyle object each time when you call setSpan(), you can do this with the next method:

CharacterStyle.wrap()

With all changes your code will be the next:

SpannableStringBuilder SpannableBuilder = new SpannableStringBuilder();
SpannableBuilder.append("1");
SpannableBuilder.setSpan(CharacterStyle.wrap(HighlightStyle), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableBuilder.append("2");
SpannableBuilder.setSpan(CharacterStyle.wrap(HighlightStyle), 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableBuilder.append("3");
SpannableBuilder.append("4");
SpannableBuilder.setSpan(CharacterStyle.wrap(HighlightStyle), 3, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);


This is how it looks in my Application:

enter image description here

Upvotes: 1

Related Questions