'Android Plurals for float values

I would like to use plurals for my Android project. However, the values I provide can be float values.

So for instance, when setting 1.5 stars, I want this to understand, it's not 1 star but 1.5 stars.

<plurals name="stars">
  <item quantity="one">%d star</item>
  <item quantity="other">%d stars</item>
</plurals>

However, the Android system seems to use integer values (%d) only.

The method looks like this:

String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)

where quantity is defined as Int.

Is there any solution for this?



Solution 1:[1]

After doing further research, it appears there is no good solution for this.

As also seen in the other answers, they always require a lot of "manual processing" to it requiring no different workflow than creating separate string resources.

The general suggestion seems to be rounding / processing the float values manually (e.g checking whether the float value matches 1.0) and then using apropriate Int values for the plurals call.

But aside from not really using plurals then this comes with the problem of other languages (e.g. I have no clue if 1.5 stars would also be plural in another language as it is in English) and thus these rounding options may not apply universally.

So the answer is: there seems to be no perfect solution (meaning solved "automatically" by the Android system).

What I actually do therefore is to simply pick exceptions and use different Strings there. So the (pseudo code) way of doing currently looks like

// optionally wrap different languages around
// if language == English

   when (amountStars) {
    is 1.0 -> getString(R.string.stars_singular, 1) 
    ... ->
    else -> getString(R.string.stars_plural, amountStars)
   }
// if language == Chinese ...

where additional cases have to be "hard coded". So for example you have to decide whether 0 means

"0 stars" (plural string) or

"no star" (singular string)

But there seems no real benefit of using plurals over separate string resources with common placeholders. On the other hand this (at last for me) gives more flexibility for formatting options. For example, one may create a text like "1 star and a half" where it becomes singular again (even though numerically we would write 1.5 stars).

Solution 2:[2]

Don't use plurals for fractional numbers. Just stick with basic string resources and use a placeholder:

<string name="fractional_stars">%1$s stars</string>

getString(R.string.fractional_stars, 0.5F.toString())

or

<string name="fractional_stars">% stars</string>

getString(R.string.half_a_star).replace("%", 0.5F.toString())

Solution 3:[3]

Simply do this:

getQuantityString(R.plurals.stars, quantity > 1f ? 2 : 1, quantity):

And replace the %d in your strings with %f.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tobias Reich
Solution 2 Johann
Solution 3