[android] ‘제로’의 Android 복수형 처리

내 strings.xml에 다음과 같은 복수 자원이있는 경우 :

   <plurals name="item_shop">
        <item quantity="zero">No item</item>
        <item quantity="one">One item</item>
        <item quantity="other">%d items</item>
   </plurals>

다음을 사용하여 사용자에게 결과를 보여줍니다.

textView.setText(getQuantityString(R.plurals.item_shop, quantity, quantity));

1 이상에서는 잘 작동하지만 수량이 0이면 “0 개 항목”이 표시됩니다. 문서에 표시된 것처럼 “0”값은 아랍어로만 지원됩니까? 아니면 내가 뭔가를 놓치고 있습니까?



답변

Android 리소스 국제화 방법은 매우 제한적입니다. 나는 표준을 사용하여 훨씬 더 나은 성공을 거두었습니다 java.text.MessageFormat.

기본적으로 다음과 같은 표준 문자열 리소스를 사용하기 만하면됩니다.

<resources>
    <string name="item_shop">{0,choice,0#No items|1#One item|1&lt;{0} items}</string>
</resources>

그런 다음 코드에서해야 할 일은 다음과 같습니다.

String fmt = getResources().getText(R.string.item_shop).toString();
textView.setText(MessageFormat.format(fmt, amount));

MessageFormat 에 대한 javadocs 에서 형식 문자열에 대해 자세히 읽을 수 있습니다.


답변

에서 http://developer.android.com/guide/topics/resources/string-resource.html#Plurals :

선택은 문법적 필요성에 따라 이루어집니다. 영어로 된 0 문자열은 수량이 0 인 경우에도 무시됩니다. 0은 문법적으로 2와 다르지 않거나 1을 제외한 다른 숫자 ( “zero books”, “one book”, “two books”등) 의 위에). 양 2에만 적용될 수있는 것처럼 두 가지 소리가 들린다는 사실에 오해하지 마십시오. 언어는 2, 12, 102 (등)가 모두 서로 닮았지만 서로 다르게 취급 될 것을 요구할 수 있습니다. 수량. 번역가의 언어가 실제로 요구하는 차이점을 알기 위해 번역자에게 의뢰하십시오.

결론적으로 ‘zero’는 특정 언어에만 사용됩니다 ( ‘two’ ‘few’등에도 동일 함). 다른 언어에는 특별한 활용이 없기 때문에 ‘zero’필드는 불필요한 것으로 간주되기 때문입니다.


답변

MessageFormat으로 전환하지 않고이 문제를 처리하는 데 사용하는 해결 방법은 다음과 같습니다.

먼저 “0”문자열을 자체 문자열 리소스로 추출합니다.

<string name="x_items_zero">No items.</string>
<plurals name="x_items">
    <!-- NOTE: This "zero" value is never accessed but is kept here to show the intended usage of the "zero" string -->
    <item quantity="zero">@string/x_items_zero</item>
    <item quantity="one">One item.</item>
    <item quantity="other">%d items.</item>
</plurals>

그런 다음 내 ResourcesUtil에 몇 가지 편리한 방법이 있습니다.

public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity) {
    if (quantity == 0) {
        return resources.getString(zeroResId);
    } else {
        return resources.getQuantityString(resId, quantity, quantity);
    }
}

public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity, Object... formatArgs) {
    if (quantity == 0) {
        return resources.getString(zeroResId);
    } else {
        return resources.getQuantityString(resId, quantity, formatArgs);
    }
}

이제 언제든지 호출하는 수량 0에 특정 문자열을 사용하고 싶습니다.

String pluralString = ResourcesUtil.getQuantityStringZero(
     getContext().getResources(),
     R.plural.x_items,
     R.string.x_items_zero,
     quantity
);

더 나은 것이 있었으면 좋겠지 만 최소한 문자열 리소스 XML을 읽을 수 있도록 유지하면서 작업을 완료합니다.


답변

Android는 CLDR 복수형 시스템을 사용하고 있으며 이는 작동 방식이 아닙니다 (변경 될 것으로 예상하지 마십시오).

시스템은 다음과 같습니다.

http://cldr.unicode.org/index/cldr-spec/plural-rules

요컨대, “1”은 숫자 1을 의미하지 않는다는 것을 이해하는 것이 중요합니다. 대신 이러한 키워드는 카테고리이고 각 카테고리에 속하는 특정 숫자 n은 CLDR 데이터베이스의 규칙에 의해 정의됩니다.

http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html

0 이외의 것에 대해 “0”을 사용하는 언어는없는 것처럼 보이지만 “1”에 0을 할당하는 언어가 있습니다. “2”에 2가 아닌 다른 숫자가 포함 된 경우가 많이 있습니다.

Android에서 의도 한대로 수행 할 수있는 경우 애플리케이션이 더 복잡한 복수 규칙을 사용하여 여러 언어로 제대로 번역되지 않을 수 있습니다.


답변

생각할 수있는 모든 시나리오를 처리하기 위해 Kotlin 확장 프로그램을 작성했습니다.

나는 zeroResId선택 사항으로, 때때로 우리는 “0 개 항목”이 아닌 “항목 없음”을 표시하여 0을 처리하려고합니다.

영어는 문법적으로 0을 복수로 취급합니다.

사용할 문자열의 선택은 전적으로 문법적 필요성에 따라 이루어집니다.

영어에서는 수량이 0 인 경우에도 0에 대한 문자열이 무시됩니다. 0은 문법적으로 2와 다르지 않거나 1을 제외한 다른 숫자 ( “zero books”, “one book”, “two books”등) 의 위에).

https://developer.android.com/guide/topics/resources/string-resource.html#Plurals

fun Context.getQuantityStringZero(
    quantity: Int,
    pluralResId: Int,
    zeroResId: Int? = null
): String {
    return if (zeroResId != null && quantity == 0) {
        resources.getString(zeroResId)
    } else {
        resources.getQuantityString(pluralResId, quantity, quantity)
    }
}


답변

데이터 바인딩을 사용하는 경우 다음과 같이이 문제를 해결할 수 있습니다.

<TextView ...
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>


답변