簡體   English   中英

用於浮點值的 Android 復數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM