Duke
Duke

Reputation: 883

Getting a String from Plurals to use in XML?

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

Answers (7)

krishnakumarp
krishnakumarp

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

Andy Briggs
Andy Briggs

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

Sanjeev
Sanjeev

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

akshay bhange
akshay bhange

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

cambunctious
cambunctious

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

Clement Cherlin
Clement Cherlin

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

gwvatieri
gwvatieri

Reputation: 5183

You have to set it by code:

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

Upvotes: 67

Related Questions