19

I have a String in my strings.xml file such as

  <string name="my_text">Hello <b>$%1$s</b>, android is cool <b>bold me</b></string>

The only way to retrieve the text with styling for bolding is using resources.getText(R.string.my_text);

Although the issue is getText does not take additional parameters for the arguments I wish to provide such as the method getString that takes arguments such as resources.getString(R.string.my_text, "I WILL BE BOLDED")

If I use getString I lose the bold, if I use getText I cant pass arguments how do I obtain both?

Jada
  • 345
  • 2
  • 5
  • 12
  • What would be wrong with just creating separate entries for the bold/non bold version? – Tim Biegeleisen Jul 20 '18 at 00:19
  • 1
    Does this answer your question? [How to use formatted strings together with placeholders in Android?](https://stackoverflow.com/questions/23503642/how-to-use-formatted-strings-together-with-placeholders-in-android) – Beloo May 14 '21 at 09:38

6 Answers6

18

To expand upon Sagar's answer, set up the string resource using CDATA:

<string name="test"><![CDATA[When no one was looking, Lex Luthor took <b>%s</b> cakes. He took %d cakes. That\'s as many as %s %s. And that\'s terrible.]]></string>

Then, retrieve the string resource using getString() and use HtmlCompat to handle the formatting:

HtmlCompat.fromHtml(getString(R.string.test, "forty", 40, "four", "tens"), HtmlCompat.FROM_HTML_MODE_COMPACT)

NOTE: The author of the answer can neither confirm nor deny that some number of cakes were consumed in the creation of this answer. However, no actual supervillains were involved, as far as you are aware.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks! This made my day! – cesards Aug 18 '20 at 18:52
  • This helped me too but I've got problems in adding extra spacing to it. Do you happen to have a solution for this: https://stackoverflow.com/questions/75821567/extra-spacing-in-strings-with-cdata – petrrr33 Mar 23 '23 at 10:03
3

With Kotlin you can create an extension function

fun Resources.getText(@StringRes id: Int, vararg formatArgs: Any?): CharSequence =
    getText(id).toSpanned().toHtml().format(*formatArgs).parseAsHtml()

and then your string from the strings.xml file such as

<string name="my_text">Hello <b>$%1$s</b>, android is cool <b>bold me</b> </string>

could be retrieved with

resources.getText(R.string.my_text, "I WILL BE BOLDED")

as the next text

Hello I WILL BE BOLDED, android is cool bold me

Yevhen Railian
  • 451
  • 5
  • 5
2

strings.xml

<string name="my_text">Hello &lt;b>$%1$s &lt;/b>, android is cool &lt;b>bold me &lt;/b></string>

code

String.format(res.getString(R.my_text.welcome_messages), "I WILL BE BOLDED");

Philipp
  • 468
  • 3
  • 24
0

You can achieve it as follows

String myText = resources.getString(R.string.my_text, "I WILL BE BOLDED");
textView.setText(Html.fromHtml(text));
Sagar
  • 23,903
  • 4
  • 62
  • 62
  • 3
    You will lose the HTML tags in that way, since `getString()` calls `toString()` internally and will escape any styling. – StevenTB Feb 21 '19 at 10:09
0

Use this instead of context.getText(), and both formatting and placeholders will work.

public static CharSequence getTextWithArgs(Context context, int id, Object... args) {
            for (int i = 0; i < args.length; ++i)
                args[i] = args[i] instanceof String? TextUtils.htmlEncode((String)args[i]) : args[i];
            return removeTrailingNewLine(
                    Html.fromHtml(String.format(Html.toHtml(new SpannedString(context.getText(id))), args)));
        }
Martin
  • 97
  • 1
  • 6
-1

You could create a helper method which takes in a string key and a formatting type, and then returns the appropriate string. Something like this:

<resources>
    <string name="text_normal">Hello World</string>
    <string name="text_bold"><b>Hello World</b></string>
</resources>

public String getFormattedString(int key, int type) {
    String packageName = getPackageName();
    String resource = key + "_" + type;
    int resourceId = getResources().getIdentifier(resource, "string", packageName);

    return getString(resourceId);
}

// now use the helper method
getFormattedString("text", "bold");
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360