TextView tv = (TextView) findViewById(R.id.abc);
String rawString = "abcdefg";
SpannableStringBuilder ssb = new SpannableStringBuilder(rawString);
ssb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, rawString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(ssb);
CharSequence cs = tv.getText();
System.out.println(cs.getClass());
The output is “class android.text.SpannedString”
Why? I expect it to be “SpannableStringBuilder”, my casting (SpannableStringBuilder ssb_2 = (SpannableStringBuilder)cs;) will give error for the example above.
Some more, the output will change to “SpannableString” if I set the buffer type of the text view to be android:bufferType="spannable"
Anyone know why?
1. Well the reason
(SpannableStringBuilder ssb_2 = (SpannableStringBuilder)cs;)doesn’t work is becauseSpannableStringBuilderimplementsCharSequence, meaning CharSequence does not know it can be casted to that. You can however do it the other way around. Does that make sense?CharSequence is a nothing/itself
SpannableStringBuilder is a: CharSequence, Spannable, Editable, etc…
2. As for why
android:bufferType="spannable"works, you are doing what I said above, the opposite. SinceSpannableStringimplementsCharSequence, it is now a child of it and therefore can be placed inCharSequence.But anyways, the correct way to put your
CharSequenceinSpannableStringBuilderis by doing:You might want to brush up on some polymorphism 🙂 but you can see this in the Android docs on SpannableStringBuilder’s constructor, or one of them at least.
Update:
From what I notice on what you are doing, what is the need to use
CharSequence? Just leave the TextView as is, meaning its returned as a String. So doing something like this would be easier:Reason that works is because String implements CharSequence as well, meaning that it as well can be passed into the SpannableStringBuilder constructor as a
CharSequence. Java does automatic casting in certain cases, including in that code right above.