Reputation: 119
In my application (in Kotlin), I have a string like this in my string.xml : <string name="buy_price">Buy %1$s %2$s for %3$s %4$s</string>
Where, for example %1$s is the amount, %2$s the item name, %3$s the amount and %4$s the fiat's name.
I want to set some colors for %1$s, %2$s, %3$s, ... . But I dont know how. I have been thinking to concatenate like 5 textView which store one part of the string but it's not very clean ...
Can you help me please
Upvotes: 1
Views: 1287
Reputation: 19622
Luiz's answer works (so I don't want the credit!) but just for anyone looking into this in general...
You can do this by wrapping your string's text in HTML tags to style it. There's two ways to display it:
Html.fromHtml(getString(R.string.whatever))
Two tags you can use:
<font color="#FF0000"></font>
- works in code and XML
<span style="color:#FF0000"></span>
- works in code, not XML, possibly allows more styling. Don't add spaces in the style bit!
As Luiz says, you need to replace <
characters with <
so getString
doesn't mess up the tags before fromHtml
can get to them (it does say it returns the text "stripped of styling information"). However!
<
- broken by getString
, works in XML<
- works in code, breaks (not parsed as a tag) in XMLSo basically:
<font>
tags or style
attributes, and change the opening <
of tags to <
<font>
tag and leave the opening <
aloneI haven't used data binding so I can't say for sure, but I'd assume that since you're running code (that's just defined in the XML) all the same caveats apply as running code in general.
Upvotes: 1
Reputation: 4961
Spannable implementation:
val category = "Monitor"
val item = "LG - 2562"
val currency = "Rs"
val amount = "1234"
val text = getString(R.string.buy_price, category, item, currency, amount)
val categoryColor = Color.BLUE
val categoryStart = text.indexOf(category)
val categoryEnd = categoryStart + category.length
val itemColor = Color.GREEN
val itemStart = text.indexOf(item)
val itemEnd = itemStart + item.length
val currencyColor = Color.RED
val currencyStart = text.indexOf(currency)
val currencyEnd = currencyStart + currency.length
val amountColor = Color.MAGENTA
val amountStart = text.indexOf(amount)
val amountEnd = amountStart + amount.length
textView.text = SpannableStringBuilder(text).apply {
setSpan(
ForegroundColorSpan(categoryColor),
categoryStart,
categoryEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
setSpan(
ForegroundColorSpan(itemColor),
itemStart,
itemEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
setSpan(
ForegroundColorSpan(currencyColor),
currencyStart,
currencyEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
setSpan(
ForegroundColorSpan(amountColor),
amountStart,
amountEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
Result:
Upvotes: 3
Reputation: 216
You can try with Html.fromHtml
I believe you can put on strings.xml something like:
<string name="buy_price">Buy <span style='color:blue'>%1$s</span> <span style='color:red'>%2$s</span> for <span style='color:green'>%3$s</span> <span style='color:yellow'>%4$s</span></string>
Then you call textView.text = Html.fromHtml(getString(R.string.buy_price), 0)
Obs: in strings.xml I replace <
with <
. It's a workaround because I believe getString will try to parse html tags like <b>
or <u>
.
Upvotes: 2