'Change color of two parts of string when using String.format()

I am using the following to show the remaining time in a word game app.

remainingTime.setText(String.format(Locale.getDefault(),"REMAINING TIME: %d MNS %d SECONDS ",(millisUntilFinished / 1000) / 60 ,(millisUntilFinished / 1000) % 60));

I want to change the color of the minute and second text. How can the colors be defined in their placeholders??

I want it look like this: enter image description here



Solution 1:[1]

If you are using Kotlin you can do it with an Extension Function.

    fun TextView.setColouredSpan(word: String, color: Int) {
        val spannableString = SpannableString(text)
        val start = text.indexOf(word)
        val end = text.indexOf(word) + word.length
        try {
            spannableString.setSpan(ForegroundColorSpan(color), start, end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            text = spannableString
        } catch (e: IndexOutOfBoundsException) {
         println("'$word' was not not found in TextView text")
    }
}

Use it after you have set your text to the TextView like so

private val blueberry by lazy { getColor(R.color.blueberry) }

textViewTip.setColouredSpan("Warning", blueberry)

Solution 2:[2]

You can use the following method to get the Digits in a different color

public SpannableString getColoredString(String string, int color){

        SpannableString spannableString = new SpannableString(string);

        for(int i = 0; i < string.length(); i++){
            if(Character.isDigit(string.charAt(i))){
                spannableString.setSpan(new ForegroundColorSpan(color), i, i+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            }
        }
        return spannableString;
    }

In your Activity code use the above function and set the return value to the textview

String text = String.format(Locale.getDefault(),"REMAINING TIME: %d MNS %d SECONDS ",(millisUntilFinished / 1000) / 60 ,(millisUntilFinished / 1000) % 60);

SpannableString string = getColoredString(text, Color.YELLOW);

remainingTime.setText(string);

enter image description here

Solution 3:[3]

In my case I had some sort of "some text [email protected] some text". Where [email protected] had to be with different color.

I tried:

<string name="myText">
some text
<font color="#FFFFFF">%1$s</font>
some text
</string>

But it looks like after getString, HtmlCompat ignores "font color", so that's why I used symbols "<" and ">" as usual symbols like that:

<string name="myText">
some text
&lt;font color="#FFFFFF"&gt; %1$s&lt;/font&gt;
some text
</string>

After that everything showed up nicely as I needed:

val email = "[email protected]"
val text = getString(R.string.myText, email)

binding.textView.text = HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ivan Wooll
Solution 2 sanoJ
Solution 3 Andrey Kijonok