Search code examples
androidstringkotlincolorstextview

Android - How can I change the color of a part of a String located in string.xml?


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


Solution

  • 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:

    enter image description here