332

In my Android app I'am going to implement my strings with internationalization. I have a problem with the grammar and the way sentences build in different languages.

For example:

"5 minutes ago" - English

"vor 5 Minuten" - German

Can I do something like the following in strings.xml?

<string name="timeFormat">{0} minutes ago</string>

And then some magic like

getString(R.id.timeFormat, dynamicTimeValue)

This behaviour would solve the other problem with different word orders as well.

Community
  • 1
  • 1
dhesse
  • 3,610
  • 2
  • 20
  • 12

5 Answers5

406

Yes, just format your strings in the standard String.format() way.

See the method Context.getString(int, Object...) and the Android or Java Formatter documentation.

In your case, the string definition would be:

<string name="timeFormat">%1$d minutes ago</string>
Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
369

If you need two variables in the XML, you can use:

%1$d text... %2$d or %1$s text... %2$s for string variables.

Example:

strings.xml

<string name="notyet">Website %1$s isn\'t yet available, I\'m working on it, please wait %2$s more days</string>

activity.java

String site = "site.tld";
String days = "11";

//Toast example
String notyet = getString(R.string.notyet, site, days);
Toast.makeText(getApplicationContext(), notyet, Toast.LENGTH_LONG).show();
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
  • 8
    The order is not as important as you say. The numbers in the string is actually the order of the parameter. Depending on language you could have the numbers in different order. – Flaxie Jan 16 '15 at 08:10
  • Important to note that you need to change the xml first, or else the .java code `getString` will not compile, because getString needs to know in advance how many parameters it needs. – lubrum Jan 27 '21 at 18:28
42

If you need to format your strings using String.format(String, Object...), then you can do so by putting your format arguments in the string resource. For example, with the following resource:

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

In this example, the format string has two arguments: %1$s is a string and %2$d is a decimal number. You can format the string with arguments from your application like this:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

If you wish more look at: http://developer.android.com/intl/pt-br/guide/topics/resources/string-resource.html#FormattingAndStyling

Yash
  • 369
  • 5
  • 18
Gabriel Lucas
  • 535
  • 4
  • 4
15

There is many ways to use it and i recomend you to see this documentation about String Format.

http://developer.android.com/intl/pt-br/reference/java/util/Formatter.html

But, if you need only one variable, you'll need to use %[type] where [type] could be any Flag (see Flag types inside site above). (i.e. "My name is %s" or to set my name UPPERCASE, use this "My name is %S")

<string name="welcome_messages">Hello, %1$S! You have %2$d new message(s) and your quote is %3$.2f%%.</string>

Hello, ANDROID! You have 1 new message(s) and your quote is 80,50%.
Gorio
  • 1,606
  • 2
  • 19
  • 32
12

Note that for this particular application there's a standard library function, android.text.format.DateUtils.getRelativeTimeSpanString().

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
Divide
  • 540
  • 5
  • 12
  • This lib function, though a wonderful idea, is plagued with grammatical errors and mistranslations in other languages...Spanish being one of them, which I find ridiculous. I felt relieved when I came across it and then pissed when I found that it was not all the magic it's supposed to be. – suomi35 Apr 11 '14 at 23:33
  • Still it's a good idea to use in general, perhaps overriding only for specific cases. That way you get free improvements on system updates (and if there's bugs, you should probably go ahead and report them). – Divide Apr 25 '14 at 20:24