Home > OS >  Android text Partial colouring
Android text Partial colouring

Time:12-17

    <string name="id">1. Tap <b><font fgcolor='#FF000000'>More</font></b> in the top-right corner.</string>

i want the "more" to be highlighted with BOLD and a different colour. Which works fine for light mode , but in night mode -> i want to be able to use a different colour. Whats the best way to do that ?

( I know about spannables , but the thing is... if i use a spannable text with indices , it will not out work with multiple languages )

CodePudding user response:

These seem to be the requirements:

  1. Support multiple languages.
  2. Each language has at least one string that will have a color and bold applied to part of the string's text that is dependent upon whether the app is running in "night" or "light" mode.
  3. "night" and "Light" mode will each use a single color that will differ from the other mode as defined in 2) above.
  4. Use a minimum number of strings.

One way to do this is to define the colors as follows:

colors.xml

<color name="my_light_dark_color">#FFFF0000</color>

colors.xml (night)

<color name="my_light_dark_color">#FFFFFFFF</color>

For "night" mode, "white" will be the color used. Otherwise, it will be "red".

Define the strings in the appropriate "string" resource files and mark the portion to which the color will be applied using Annotation spans. Below I use English and French for the example.

strings.xml

<string name="hello_string">Hello! How are <b><annotation color="my_light_dark_color">you</annotation></b>?</string>

strings.xml (fr)

<string name="hello_string">Bonjour! Comment allez-<b><annotation color="my_light_dark_color">vous</annotation></b>?</string>

Now that our resources are in place, we need a little code to splice it all together.

val textToColor = binding.textView.text.toSpannable()
val lightDarkColor =
        ResourcesCompat.getColor(resources, R.color.my_light_dark_color, requireActivity().theme)

// Find all Annotation spans that specifies a color as a key with the right value.
textToColor.getSpans<android.text.Annotation>(0, textToColor.length)
    .filter { it.key == "color" && it.value == "my_light_dark_color"}.forEach {
        replaceSpan(textToColor, it, ForegroundColorSpan(lightDarkColor))
    }
binding.textView.text = textToColor

fun replaceSpan(spannable: Spannable, oldSpan: Any, newSpan: Any) {
    val spanStart = spannable.getSpanStart(oldSpan)
    val spanEnd = spannable.getSpanEnd(oldSpan)
    val flags = spannable.getSpanFlags(oldSpan)
    spannable.removeSpan(oldSpan)
    spannable.setSpan(newSpan, spanStart, spanEnd, flags)
}

The code above will require defining two values for the text color to be applied and one string for each language. The Annotation spans can be applied to each language as required.

For more information see

  • Related