1

I am formatting strings dynamically, as the following example from Android documentation:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

Then I set values like this:

var text = getString(R.string.welcome_messages, username, mailCount)

How can I set the green color for username and red for mailCount?

I need it to work for multiple locales, too. So I can't just hardcoded positions myself.

Previously I split this string into 4 parts and then could easily use SpannableBuilder to change colors.

HTML and CDATA are not appropriate. We need to keep the same strings for Android and iOS.

M--
  • 25,431
  • 8
  • 61
  • 93
Viktor Vostrikov
  • 1,322
  • 3
  • 19
  • 36

3 Answers3

2

You can use SpannableString and setSpan based on your requirement.

<string name="welcome_message">Hello, %1$s! You have %2$d new messages.</string>

void setSpannableTextWithColor(TextView view, int resourceId, String username, int userColor, int messageCount, int countColor) {
    String fulltext = getString(resourceId, username, messageCount);

    view.setText(fulltext, TextView.BufferType.SPANNABLE);
    Spannable str = (Spannable) view.getText();

    int usernameIndex = fulltext.indexOf(username);
    str.setSpan(new ForegroundColorSpan(userColor), usernameIndex, usernameIndex + username.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    int countIndex = fulltext.indexOf(String.valueOf(messageCount));
    str.setSpan(new ForegroundColorSpan(countColor), countIndex, countIndex + String.valueOf(messageCount).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} 

setSpannableTextWithColor(findViewById(R.id.text_view1), R.string.welcome_message, "Viktor Vostrikov", Color.GREEN, 122, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view2), R.string.welcome_message, "Виктор Востриков", Color.GREEN, 2, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view3), R.string.welcome_message, "فيكتور فوستريكوف", Color.GREEN, 2000, Color.RED);

Output:

![enter image description here

Md. Asaduzzaman
  • 14,963
  • 2
  • 34
  • 46
1

Declare string

<string name="string_formatted"><![CDATA[ Hello, <font color=#145A14> %1$s!</font> You have %2$d new messages]]></string>

In Activity

TextView tv = findViewById(R.id.mytext);
tv.setText(Html.fromHtml(getString(R.string.html_formatted,"XYZ", 5)));
Kishan Maurya
  • 3,356
  • 8
  • 21
  • Thanks for html answer. Sadly, I will edit my post, that I would like solution without CDATA, because IOS does not support that. We want same strings in iOS as well as android – Viktor Vostrikov Feb 16 '20 at 09:27
0

Using Jetpack core-ktx, you can write it succinctly as:

val s = "Beautiful City".toSpannable()

s[0..9] = ForegroundColorSpan(Color.GREEN)
Gulzar Bhat
  • 1,255
  • 11
  • 13