Getting a String from Plurals to use in XML?

AndroidAndroid Xml

Android Problem Overview


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?

Android Solutions


Solution 1 - Android

You have to set it by code:

...setText(yourContext.getResources().getQuantityString(R.plurals.cats, catsCountVar));

Solution 2 - Android

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.

Solution 3 - Android

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

Solution 4 - Android

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.

Solution 5 - Android

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  
)

Solution 6 - Android

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);
    }
}

Solution 7 - Android

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDukeView Question on Stackoverflow
Solution 1 - AndroidgwvatieriView Answer on Stackoverflow
Solution 2 - AndroidClement CherlinView Answer on Stackoverflow
Solution 3 - AndroidAndrew BriggsView Answer on Stackoverflow
Solution 4 - AndroidkrishnakumarpView Answer on Stackoverflow
Solution 5 - AndroidSanjeevView Answer on Stackoverflow
Solution 6 - AndroidcambunctiousView Answer on Stackoverflow
Solution 7 - Androidakshay bhangeView Answer on Stackoverflow