Is it possible to set multiple styles for different pieces of text inside a TextView?
For instance, I am setting the text as follows:
tv.setText(line
The list of supported tags is:
If you use a string resource, you can add some simple styling, such as bold or italic using HTML notation. The currently supported tags are:
B
(bold),I
(italic),U
(underline),TT
(monospace),BIG
,SMALL
,SUP
(superscript),SUB
(subscript), andSTRIKE
(strikethrough). So, for example, inres/values/strings.xml
you could declare this:<resource> <string id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string> </resources>
(From http://developer.android.com/guide/faq/commontasks.html#selectingtext — Web Archive link, <resource>
typo is in original!)
It also shows that Html.fromHtml
isn't really needed in simple cases.
If you don't feel like using html, you could just create a styles.xml and use it like this:
TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(text, TextView.BufferType.SPANNABLE);
Slightly off-topic, but I found this too useful not to be mentioned here.
What if we would like to read the the Html text from string.xml resource and thus make it easy to localize. CDATA make this possible:
<string name="my_text">
<![CDATA[
<b>Autor:</b> Mr Nice Guy<br/>
<b>Contact:</b> myemail@grail.com<br/>
<i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i>
]]>
</string>
From our Java code we could now utilize it like this:
TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setText(Html.fromHtml(getString(R.string.my_text)));
I did not expect this to work. But it did.
Hope it's useful to some of you!
Yes, it is possible using SpannedString
. If you are using Kotlin, it becomes even easier to do by using core-ktx
, as it provides a domain-specific-language (DSL) for doing this:
val string: SpannedString = buildSpannedString {
bold {
append("1111")
}
append("Devansh")
}
More options provided by it are:
append("Hello There")
bold {
append("bold")
italic {
append("bold and italic")
underline {
append("then some text with underline")
}
}
}
At last, you can just to:
textView.text = string
It might be as simple as leveraging the String's length() method:
Split the text string in the Strings XML file into as many sub-strings (a seperate strings from Android's point of view) as many you need different styles, so it could be like: str1, str2, str3 (as in your case), which when joined together are the whole single string you use.
And then simply follow the "Span" method, just like you presented with your code - but instead of a single string, combine all the substrings merging them into a single one, each with a different custom style.
You still use the numbers, however not directly - they're no more take a hardcoded form (as in your code) now, but they're being substituted with the combined length() methods (note two stars preceding and suffixing the str.length() in place of the absolute number to extuinguish the change):
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
for the first string size, then str.length() + 1, str.length() + str2.length() for the second string size, and so on with all the substrings, instead of e.g. 0,7 or 8,19 and so on...
Here is an easy way to do so using HTMLBuilder
myTextView.setText(new HtmlBuilder().
open(HtmlBuilder.Type.BOLD).
append("Some bold text ").
close(HtmlBuilder.Type.BOLD).
open(HtmlBuilder.Type.ITALIC).
append("Some italic text").
close(HtmlBuilder.Type.ITALIC).
build()
);
Result:
Some bold text Some italic text