Reputation: 3449
My application has only polish strings, it's default language of an app. Here you can see example plurals placed under res/vaules:
<plurals name="number_of_vouchers">
<item quantity="one">%d kupon</item>
<item quantity="few">%d kupony</item>
<item quantity="many">%d kuponów</item>
<item quantity="other">%d kuponów</item>
</plurals>
Here you have test activity class:
class DevTest : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dev_test)
val stb = StringBuilder()
for (j in 1..30) {
stb.append(resources.getQuantityString(R.plurals.number_of_vouchers, j, j) + "\n")
}
testTV.text = stb.toString()
}
}
This how example test looks like on system settings with Polish language set as default (works as it supposed to):
This how example test looks like on system settings with English language set as default (doesn't work even if app has only Polish language):
You can see that for English system language it's omits
<item quantity="few">%d kupony</item>
even if app has only one language, and it's not English.
Upvotes: 7
Views: 2233
Reputation: 3285
As per Android official documentation here
few : When the language requires special treatment of "small" numbers (as with 2, 3, and 4 in Czech; or numbers ending 2, 3, or 4 but not 12, 13, or 14 in Polish).
So, In the Polish
. If the numbers are ending with 2,3,4 (But not 12,13,14) it is taking plural of few
.
--- EDITED --
For your app, polish is the only language.(under res/values
). Now when your system language is polish. These plurals will be treated as Polish. So it's displaying as per my ans. Now when you change the system language to English. The same plurals will be treated as English. Hence no change in at 22,23,24. That's because res/values
behaves as per system default language when no specific resource type is defined.
Also check the official documentation How Android finds the best-matching resource
Upvotes: 2
Reputation: 3449
Fix for this is for example to wrap context with overridden locale. For example:
companion object {
fun wrap(context: Context?, language: String): ContextWrapper {
if(context == null)
return CustomContextWrapper(context)
val config = context.resources.configuration
val sysLocale: Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getSystemLocale(config)
} else {
getSystemLocaleLegacy(config)
}
if (language.isNotEmpty() && !sysLocale.language.equals(language)) {
val locale = Locale(language)
Locale.setDefault(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setSystemLocale(config, locale)
} else {
setSystemLocaleLegacy(config, locale)
}
return CustomContextWrapper(context.createConfigurationContext(config))
}
return CustomContextWrapper(context)
}
private fun getSystemLocaleLegacy(config: Configuration): Locale {
return config.locale
}
@TargetApi(Build.VERSION_CODES.N)
private fun getSystemLocale(config: Configuration): Locale {
return config.locales.get(0)
}
private fun setSystemLocaleLegacy(config: Configuration, locale: Locale) {
config.locale = locale
}
@TargetApi(Build.VERSION_CODES.N)
private fun setSystemLocale(config: Configuration, locale: Locale) {
config.setLocale(locale)
}
}
And called within Activity like:
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(CustomContextWrapper.wrap(newBase, "pl"))
}
Resolved thanks to original fix link
I couldn't find that issue on google's bug tracker so I assume that it works as it should.
Upvotes: 1