SpannableStringBuilder to create String with multiple fonts/text sizes etc Example?
I need to create a String placed in a TextView that will display a string like this:
First Part Not Bold BOLD rest not bold
So I want to know how I could use SpannableStringBuilder
to do this?
I could use three TextEdit to accomplish this but I would like to use best solution.
First Part Not Bold BOLD rest not bold
You can do this either as @Rajesh suggested or by this.
String normalBefore= "First Part Not Bold ";
String normalBOLD= "BOLD ";
String normalAfter= "rest not bold";
String finalString= normalBefore+normalBOLD+normalAfter;
Spannable sb = new SpannableString( finalString );
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size
to show this in TextView
textview.setText(sb, TextView.BufferType.SPANNABLE);
The accepted answer is fine (and I upvoted it), but it fails to use the SpannableStringBuilder as the submitter requested. As I had a case where the Builder made the most sense, here is the code for that (with a bonus use of also changing the color of the text if that is helpful to others). Note that you could also provide the initial string to the SpannableStringBuilder constructor, but I set it here to use "append" to be clear that you can append a lot before your desired "bold" text and then just record the start as shown. I would suspect that this is also faster code than the accepted answer.
SpannableStringBuilder longDescription = new SpannableStringBuilder();
longDescription.append("First Part Not Bold ");
int start = longDescription.length();
longDescription.append("BOLD");
longDescription.setSpan(new ForegroundColorSpan(0xFFCC5500), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.append(" rest not bold");
If you are using Kotlin you can do the following using the android-ktx library
val s = SpannableStringBuilder()
.append("First Part Not Bold ")
.bold { append("BOLD") }
.append("Rest not bold")
The bold
is an extension function on SpannableStringBuilder
. You can see the documentation here for a list of operations you can use.
Another example:
val s = SpannableStringBuilder()
.color(green, { append("Green text ") })
.append("Normal text ")
.scale(0.5, { append("Text at half size " })
.backgroundColor(green, { append("Background green") })
Where green
is a resolved RGB color.
It is even possible to nest spans so you end up with an embedded DSL:
bold { underline { italic { append("Bold and underlined") } } }
You will need the following in your app module level build.gradle
for it to work:
repositories {
google()
}
dependencies {
implementation "androidx.core:core-ktx:1.2.0"
}
From API 21 SpannableStringBuilder includes a simple method to do this. Here is a solution example:
SpannableStringBuilder builder= new SpannableStringBuilder();
StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
builder.append("First Part Not Bold ")
.append("BOLD ", boldSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
.append("rest not bold");
Since it is a good chance you do not support API 21 only you can duplicate the code from that method:
public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
int start = length();
append(text);
setSpan(what, start, length(), flags);
return this;
}
Use HTML code in TextView using the Html
class:
Spanned styledText = Html.fromHtml("First Part Not Bold <b>BOLD</b> rest not bold");
textView.setText(styledText);