[英]Android Plurals for float values
我想為我的 Android 項目使用復數形式。 但是,我提供的值可以是浮點值。
因此,例如,當設置 1.5 星時,我想讓它明白,它不是 1 星而是 1.5 星s 。
<plurals name="stars">
<item quantity="one">%d star</item>
<item quantity="other">%d stars</item>
</plurals>
但是,Android 系統似乎只使用整數值 (%d)。
該方法如下所示:
String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
其中數量定義為Int 。
有什么解決辦法嗎?
首先我要說:非常有趣的問題。
其次,這是解決方案:使用%s而不是%d作為占位符。
<plurals name="stars">
<item quantity="one">%s star</item>
<item quantity="other">%s stars</item>
</plurals>
然后你必須在數量上使用Math.ceil()
。 因此1.1f
例如將成為2
,因此你的文字會從明星變成明星秒 。
我在Kotlin和Java中編寫了這個解決方案。
對於Kotlin,我寫了一個擴展函數,如下所示:
fun Resources.getQuantityString(@PluralsRes pluralResId: Int, pluralValue: Float) =
this.getQuantityString(R.plurals.stars, Math.ceil(pluralValue.toDouble()).toInt(), pluralValue)
這將被稱為: tvText.text = resources.getQuantityString(R.plurals.stars, 1.1f)
對於Java,我的解決方案如下所示:
import android.content.res.Resources;
import android.support.annotation.PluralsRes;
public class PluralResource {
public static String get(Resources resources, @PluralsRes int pluralResId, float pluralValue) {
return resources.getQuantityString(pluralResId, (int) Math.ceil(pluralValue), pluralValue);
}
}
這被稱為:
tvText.text = PluralResource.get(resources, R.plurals.stars, 1.1f)
只需這樣做:
getQuantityString(R.plurals.stars, quantity > 1f ? 2 : 1, quantity):
並用%f替換字符串中的%d。
不要對小數使用復數形式。 只需堅持基本的字符串資源並使用占位符:
<string name="fractional_stars">%1$s stars</string>
getString(R.string.fractional_stars, 0.5F.toString())
要么
<string name="fractional_stars">% stars</string>
getString(R.string.half_a_star).replace("%", 0.5F.toString())
經過進一步研究后,似乎沒有好的解決方案 。
正如在其他答案中看到的那樣,它們總是需要大量的“手動處理”,而不需要創建單獨的字符串資源。
一般建議似乎是手動舍入/處理浮點值(例如,檢查浮點值是否匹配1.0),然后對復數調用使用適當的Int值。
但除了沒有真正使用復數之外,這還伴隨着其他語言的問題(例如,我不知道1.5星也會在另一種語言中復數,因為它是英語)因此這些舍入選項可能不適用於普遍。
所以答案是:似乎沒有完美的解決方案(意思是由Android系統“自動”解決)。
因此我實際上只是選擇異常並在那里使用不同的字符串。 所以(偽代碼)的做法目前看起來像
// 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 ...
其他案件必須“硬編碼”。 因此,例如,你必須決定0是否意味着
“ 0 star s ”(復數字符串)或
“ 沒有明星 ”(單數字符串)
但是,對於使用共同占位符的單獨字符串資源,使用復數似乎沒有任何實際好處。 另一方面,這(對我而言)為格式化選項提供了更大的靈活性。 例如,人們可以創建一個像“1星半”的文本,它再次成為單數(盡管在數字上我們會寫1.5星)。
getQuantityString 接受類型為 Int 和 Object 的數量... formatArgs 如果將數量四舍五入為 Int,您將確保 1.0 -> 1.99 中的任何值都是單個項目,除此之外是復數
resources.getQuantityString(
R.plurals.products_left_in_stock_message_plural,
leftInStock.toInt(), leftInStock.toString()
)
所以你只將它四舍五入,但將實際值作為參數傳遞
<plurals name="products_left_in_stock_message_plural">
<item quantity="one">Only one item is available from this product</item>
<item quantity="other">There are only %s item is available from this product</item>
</plurals>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.