Android – error merging spannable objects
I want to merge three spannable objects. This code works normally:
Spannable s1 = new SpannableStringBuilder("bold");
s1.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, s1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Spannable s2 = new SpannableStringBuilder("not");
Spannable s3 = new SpannableStringBuilder("BOLD");
s3.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, s3.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
finishSpan = (Spanned) TextUtils.concat(s1,s2);
finishSpan = (Spanned) TextUtils.concat(finishSpan,s3);
////////////////////////////////////////////////// ////
Or finishspan = (spanned) textutils.concat (S1, S2, S3);
I have the same code, but when I merge three objects, the result is wrong. I have checked whether the type of some elements is correct. Beginingofmodifiedspennable is bold, selectionspannable is normal, endofmodifiedspennable is bold, but their combination is wrong. Only the last part of the result string is bold. Why is this? I have the same code above, the effect is very good!
Spannable str = contentText.getText();
Spannable selectionSpannable = new SpannableStringBuilder(str, selectionStart, selectionEnd);
StyleSpan[] ss = selectionSpannable.getSpans(0, selectionSpannable.length(), StyleSpan.class);
boolean exists = false;
for (int i = 0; i < ss.length; i++) {
if (ss[i].getStyle() == android.graphics.Typeface.BOLD){
selectionSpannable.removeSpan(ss[i]);
exists = true;
}
}
if (!exists){
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else {
Spannable endOfModifiedSpannable = new SpannableStringBuilder(str, selectionEnd, contentText.getText().length());
Spannable beginningOfModifiedSpannable = new SpannableStringBuilder(str, 0, selectionStart);
Spanned finishSpan = null;
if(beginningOfModifiedSpannable.length() > 0) {
if(endOfModifiedSpannable.length() > 0) {
finishSpan = (Spanned) TextUtils.concat(beginningOfModifiedSpannable,selectionSpannable);
finishSpan = (Spanned) TextUtils.concat(finishSpan,endOfModifiedSpannable);
}
else {
finishSpan = (Spanned) TextUtils.concat(beginningOfModifiedSpannable,selectionSpannable);
}
}
else {
if(endOfModifiedSpannable.length() > 0) {
finishSpan = (Spanned) TextUtils.concat(selectionSpannable,endOfModifiedSpannable);
}
else {
finishSpan = selectionSpannable;
}
}
contentText.setText(finishSpan);
I repeat, I have checked that three parts are true. For example, I have three parts: Hello, world
I noticed that the first merger was right:
finishSpan = (Spanned) TextUtils.concat(beginningOfModifiedSpannable,selectionSpannable);
Looks like Hello, wor
But the second is wrong
finishSpan = (Spanned) TextUtils.concat(finishSpan,endOfModifiedSpannable);
Or this combination is wrong:
finishSpan = (Spanned) TextUtils.concat(finishSpan,selectionSpannable,endOfModifiedSpannable);
The result of the error string is: Hello, world
But the real result must be:
Hello, world
crap!
resolvent:
The problem is that you are likely to use the same characterstyle instance for both parts, the first and third. Each time you add a style to a spannable object, you need to use a new instance
for example
SpannableStringBuilder ssb = new SpannableStringBuilder("Hello,world");
CharacterStyle c = new StyleSpan(Typeface.BOLD);
ssb.setSpan(c, 0, 3, 0);
ssb.setSpan(c, 9, 11, 0);
This will lead to Hello, world
To get the correct results, you must do the following:
SpannableStringBuilder ssb = new SpannableStringBuilder("Hello,world");
CharacterStyle c = new StyleSpan(Typeface.BOLD);
CharacterStyle c2 = new StyleSpan(Typeface.BOLD);
ssb.setSpan(c, 0, 3, 0);
ssb.setSpan(c2, 9, 11, 0);