Reputation: 883
I am using Plurals to simplify my code. e.g., I used to have
<string name="cat">Cat</string>
<string name="cats">Cats</string>
Using Plurals instead of multiple strings, I now have
<plurals name="cats">
<item quantity="one">Cat</item>
<item quantity="other">Cats</item>
</plurals>
However, I used to retrieve strings to use as titles or summaries in my XML. e.g.,
android:title="@string/cats"
Having removed that string in favor of a Plural, I am now unsure how to retrieve my string from XML. I did make a naive attempt with
android:title="@plurals/cats"
but this just gives me @1234567890
instead of Cats
(or Cat
).
Anyone know if it is possible to retrieve a string out of a Plural from XML?
Upvotes: 67
Views: 32683
Reputation: 9295
This is now possible from xml. If you have arguments in the plural forms, you have to remember to pass the quantity variable twice. Like in the below example.
<plurals name="number_of_students_in_topic">
<item quantity="zero">None are currently in this topic.</item>
<item quantity="one">One student is currently in this topic.</item>
<item quantity="other">%d students are currently in this topic.</item>
</plurals>
In xml with data binding.
android:text="@{@plurals/number_of_students_in_topic(count, count)}"
This is because, the plurals with arguments are converted in code (In *BindingImpl classes) using getResources().getQuantityString(int id, int quantity, Object... formatArgs)
The first count is to select the right plural form, and the second one is to format the String with right values.
Upvotes: 11
Reputation: 485
This can now be done in XML, using a data binding expression:
android:text="@{@plurals/cats(catCount)}"
See this page in the docs for more information: https://developer.android.com/topic/libraries/data-binding/expressions#resources
Upvotes: 16
Reputation: 4375
If your string includes string formatting with a number then you need to sent the integer variable twice, example
strings.xml
<resources>
<plurals name="numberOfMinute">
<item quantity="one">%d minute</item>
<item quantity="other">%d minutes</item>
</plurals>
</resources>
in java
int min = getNumberOfMinute();
Resources res = getResources();
String formattedStr = res.getQuantityString(
R.plurals.numberOfMinute,
min,
min
); //this will return "20 minutes" or "1 minute" depending on variable
Kotlin File
resources.getQuantityString(
R.plurals.numberOfMinute, //plural from strings.xml file
min, //quantity
min //var arg
)
Upvotes: 6
Reputation: 2504
updated answer for Kotlin
strings.xml
<plurals name="lbl_items_selected">
<item quantity="one">%d item Selected</item>
<item quantity="other">%d items Selected</item>
</plurals>
Kotlin File
resources.getQuantityString(
R.plurals.lbl_items_selected, //plural from strings.xml file
size, //quantity
size //var arg
)
this will return :
if size = 1 : 1 item selected
if size = 2 (or more) : 2(given size) items selected
Upvotes: 1
Reputation: 9582
Here is a way to use a plural resource as an attribute of your custom View.
src/main/res/xml/layout.xml
<com.mypackage.MyView
app:foo="@plurals/cats"/>
src/main/res/values/attrs.xml
<resources>
<declare-styleable name="MyView">
<attr name="foo"/>
</declare-styleable>
</resources>
MyView.java
public class MyView extends View {
private int fooResId;
private int quantity;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);
fooResId = a.getResourceId(R.styleable.MyView_foo, 0);
a.recycle();
}
// this will return "Cat" or "Cats" depending on the value of quantity
private String getFooString() {
return getContext().getResources().getQuantityString(fooResId, quantity);
}
}
Upvotes: 1
Reputation: 488
You can have the run-time benefits of Plurals and the static benefit of string resources by leaving your string resources where they are and referring to them in your plural resources.
From https://developer.android.com/guide/topics/resources/string-resource.html#Plurals (emphasis added).
<item>
A plural or singular string. The value can be a reference to another string resource. Must be a child of a element. Beware that you must escape apostrophes and quotation marks. See Formatting and Styling, below, for information about to properly style and format your strings. Example:
<string name="cat">Cat</string>
<string name="cats">Cats</string>
<plurals name="cats">
<item quantity="one">@string/cat</item>
<item quantity="other">@string/cats</item>
</plurals>
Now you can use android:title="@string/cats"
in XML files and also use
getQuantityString(R.plurals.cats, numberOfCats)
at runtime.
Upvotes: 15
Reputation: 5183
You have to set it by code:
...setText(yourContext.getResources().getQuantityString(R.plurals.cats, catsCountVar));
Upvotes: 67