एंड्रॉइड प्लुरल का उपचार "शून्य"


83

यदि मेरे स्ट्रिंग्स में निम्न बहुवचन ressource है। 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 आइटम" देखता हूं। क्या "शून्य" मूल्य केवल अरबी भाषा में समर्थित है क्योंकि दस्तावेज़ीकरण इंगित करता है? या क्या मैं कुछ न कुछ भूल रहा हूं?


21
यह समस्या यहां बताया जाता है code.google.com/p/android/issues/detail?id=8287 । अभी तक तय नहीं है: /
OcuS

5
मुझे नहीं लगता कि इसका बग: ध्यान दें कि चयन व्याकरणिक आवश्यकता के आधार पर किया गया है। अंग्रेजी में शून्य के लिए एक स्ट्रिंग को अनदेखा किया जाएगा भले ही मात्रा 0 हो, क्योंकि 0 व्याकरणिक रूप से 2 से अलग नहीं है, या 1 ("शून्य पुस्तकें", "एक किताब", "दो किताबें", और इसी तरह के अलावा अन्य कोई भी संख्या नहीं है) पर)
बाइटमे

1
अफसोस की बात है कि सभी भाषाएँ अंग्रेजी के समान नहीं हैं
आर्मंड

2
मुझे लगता है कि यह इस अर्थ में एक बग है, व्याकरण एक तरफ, 99% बार मुझे इसका उपयोग करने की आवश्यकता है, मुझे लापता कार्यक्षमता की आवश्यकता थी । तो, हाँ, मेरा मानना ​​है कि यह एक बग है जिसे Google शायद कभी ठीक नहीं करेगा। जैसे, एक वर्कअराउंड की आवश्यकता है। आप देखते हैं, एपीआई उपभोक्ताओं की मदद करने के लिए हैं, चीजों को प्राप्त करने के लिए, विशेष रूप से वास्तविक दुनिया से सार अवधारणाओं का प्रतिनिधित्व करने के लिए नहीं। यदि शून्य को बॉक्स से बाहर का समर्थन किया गया होता, तो दोनों समूह (जिन्हें व्याकरण की शुद्धता की आवश्यकता होती है और जो नहीं करते हैं), कुछ अलग उपयोग किए बिना दूर हो सकते हैं।
मार्टिन मार्कोसिनी

जवाबों:


90

अंतर्राष्ट्रीयकरण की 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 में प्रारूप स्ट्रिंग के बारे में अधिक पढ़ सकते हैं


7
अच्छा काम है। मैं अभी कल्पना कर सकता हूं कि मेरे आवेदन का अनुवाद करने वाले लोगों को मेरी फाइलों में किस तरह का गड़बड़झाला मिलेगा ... :)
OcuS

1
मैं "कुछ" संख्या (2,3,4 को समाप्त करने वाली संख्या, लेकिन 12,13,14 के साथ समाप्त नहीं) के लिए प्रारूप स्ट्रिंग की रचना कैसे करूं?
वोकिलम

3
वाह, यह बदसूरत है। इस तरह तर्क कोड में जाना चाहिए, अनुवाद नहीं। नंबरों को केवल संख्या के लिए भाषा अंतर के साथ मदद करने के लिए माना जाता है। "कुछ" के लिए अनुशंसा के साथ, आपने अब तर्क और अनुवाद में तर्क को सफलतापूर्वक स्थानांतरित कर दिया है।
डेनिसK

2
यह निश्चित रूप से अच्छा काम नहीं है। बस no_items के लिए एक स्ट्रिंग जोड़ें और यदि पहले एक खंड। यदि (आइटम .ाउंट == 0) {स्ट्रिंग का उपयोग करें} और {बहुवचन का उपयोग करें} और तब अनुवादकों को स्ट्रिंग्स में समस्या से निपटने दें।
xml

2
@ MartínMarconcini आप सही हैं ... 3 साल बाद :-)
ग्रेबेल्ड गीक जूल

47

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

ध्यान दें कि चयन व्याकरणिक आवश्यकता के आधार पर किया जाता है। अंग्रेजी में शून्य के लिए एक स्ट्रिंग को अनदेखा किया जाएगा भले ही मात्रा 0 हो, क्योंकि 0 व्याकरणिक रूप से 2 से अलग नहीं है, या 1 ("शून्य पुस्तकें", "एक किताब", "दो किताबें", और इसी तरह के अलावा अन्य कोई भी संख्या नहीं है) पर)। या तो इस तथ्य से गुमराह न हों कि, दो ध्वनियाँ, जैसे यह केवल मात्रा 2 पर लागू हो सकती हैं: एक भाषा के लिए 2, 12, 102 (और इसी तरह) की आवश्यकता हो सकती है, सभी को एक दूसरे की तरह माना जाता है, लेकिन दूसरे से अलग तरह से मात्रा। आपकी अनुवादक पर यह जानने के लिए कि उनकी भाषा वास्तव में किन बातों पर ज़ोर देती है।

निष्कर्षतः, 'शून्य' केवल कुछ भाषाओं के लिए उपयोग किया जाता है (वही 'दो' 'कुछ' आदि के लिए जाता है) क्योंकि अन्य भाषाओं में एक विशेष संयुग्मन नहीं होता है और इसलिए 'शून्य' क्षेत्र को अनावश्यक माना जाता है


4
"अंग्रेजी में शून्य के लिए एक स्ट्रिंग को अनदेखा किया जाएगा भले ही मात्रा 0 हो, क्योंकि 0 व्याकरणिक रूप से 2 से अलग नहीं है" ... कैसे "मेरे पास कोई फल नहीं है" बनाम "मेरे पास एक Apple और एक नारंगी है"?
जेफरी बट्टमैन

4
शब्द 0 बनाम 2 के बहुत सारे अलग-अलग तरीके हैं। लेकिन इन संसाधनों के पीछे का विचार उन्हें एक संख्या के साथ उपयोग करना है। तो कुछ इस तरह है: मेरे पास 0 सेब हैं। मेरे पास 1 सेब है। मेरे पास 2 सेब हैं।
बाइटमेई

4
यह बहुत बुरा है। उन्हें भाषा-विशिष्ट धारणा बनाने की कोशिश नहीं करनी चाहिए थी। हर कोई जानता है कि उपयोग किए गए प्लुरल को इससे भ्रमित किया गया है
जेफरी ब्लाटमैन

2
@ miracle2k: संदेश श्रेणी के द्वारा अनुवादित नहीं किए जाते हैं, इसलिए आपके पास एक भाषा में जो भी श्रेणियां या संदेश हैं वे किसी अन्य भाषा को प्रभावित नहीं करते हैं। इसलिए यदि आपके पास केवल शून्य गणना के लिए अंग्रेजी में एक 'शून्य' वर्ग संदेश है, और दूसरी भाषा 'शून्य' वर्ग का उपयोग 10,100 की गिनती के लिए कर रही है जो कोई फर्क नहीं पड़ता क्योंकि आप 'शून्य' वर्ग संदेश का अनुवाद नहीं करते हैं। दूसरी ओर: यदि आप अंग्रेजी में 0 गिनती के लिए एक अलग संदेश संसाधन बनाते हैं, तो आप अनुवादकों के लिए एक वर्कफ़्लो समस्या पैदा कर रहे हैं क्योंकि यह मामला पहले से ही उनकी भाषा में मूल 'शून्य' वर्ग संदेश द्वारा कवर किया गया है।
बेसल शिशानी

2
यह सच है कि एक सुविधा सुविधा के रूप में अंग्रेजी में "शून्य" श्रेणी को सक्षम किया जा सकता है, लेकिन यह "साफ" नहीं है, और केवल बुरे व्यवहार को प्रोत्साहित करता है। आपको टेक्स्ट को "शून्य" स्ट्रिंग में आइटम जोड़ने के लिए प्रोत्साहित करने का विचार मिल सकता है - फिर संभवतः अप्रतिस्पर्धी। कड़ाई से बोलते हुए, ओपी का उदाहरण ("कोई आइटम नहीं") पहले से ही उस समस्या को प्रदर्शित करता है, क्योंकि एक अनुवादक 0-केस को शब्दों के रूप में अच्छी तरह से उपयोग करना चाहता है। यदि आप "% s आइटम" को "% s आइटम" का एकवचन संस्करण मानते हैं, और "कोई आइटम नहीं" तो भाषाई रूप से पूरी तरह से अलग होने के लिए यह कोई समस्या नहीं है।
चमत्कार

15

मैसेजफ़ॉर्मैट पर स्विच किए बिना इस समस्या को हल करने के लिए एक वर्कअराउंड का उपयोग कर रहा हूं।

पहले मैं "शून्य" स्ट्रिंग को अपने स्वयं के स्ट्रिंग संसाधन में निकालता हूं।

<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);
    }
}

अब कभी भी मैं मात्रा शून्य के लिए एक विशिष्ट स्ट्रिंग का उपयोग करना चाहता हूं जिसे मैं कहता हूं:

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

काश कुछ बेहतर होता लेकिन स्ट्रिंग संसाधन XML को सुपाच्य रखते हुए यह काम कम से कम हो जाता।


इसका उपयोग करते हुए, "<आइटम मात्रा =" शून्य ">" वास्तव में कभी उपयोग नहीं किया जाएगा?
Android डेवलपर

4
सही '<आइटम मात्रा = "शून्य">' का उपयोग नहीं किया जाएगा। मेरे पास वहाँ है क्योंकि मुझे लगता है कि यह शून्य के लिए उस मूल्य के इच्छित उपयोग को स्पष्ट करने में मदद करता है।
जस्टिन फिडलर

ऐसा ही सोचा था। यह अनुवादकों को यह समझने में मदद कर सकता है कि हालांकि क्या चल रहा है।
Android डेवलपर

13

एंड्रॉइड CLDR plurals सिस्टम का उपयोग कर रहा है, और यह सिर्फ यह नहीं है कि यह कैसे काम करता है (इसलिए इसे बदलने की उम्मीद न करें)।

प्रणाली यहाँ वर्णित है:

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

संक्षेप में, यह समझना महत्वपूर्ण है कि "एक" का अर्थ नंबर 1 नहीं है। इसके बजाय ये कीवर्ड श्रेणी हैं, और प्रत्येक श्रेणी से संबंधित विशिष्ट संख्या सीएलडीआर डेटाबेस में नियमों द्वारा परिभाषित हैं:

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

जबकि ऐसी कोई भाषा नहीं है जो 0 के अलावा किसी भी चीज़ के लिए "शून्य" का उपयोग करती है, ऐसी भाषाएं हैं जो 0 से "एक" को असाइन करती हैं। निश्चित रूप से बहुत सारे मामले हैं जहां "दो" में सिर्फ 2 के अलावा अन्य संख्याएं हैं।

यदि एंड्रॉइड जहां आपको वह करने की अनुमति देता है जो आप चाहते थे, तो आपके एप्लिकेशन को अधिक जटिल बहुवचन नियमों के साथ किसी भी संख्या में भाषाओं में ठीक से अनुवाद नहीं किया जा सकता है।


5
कई सवालों के जवाब बायलरप्लेट / शब्दशः कॉपी करते समय सावधान रहें, ये समुदाय द्वारा "स्पैम" के रूप में चिह्नित किए जाते हैं। यदि आप ऐसा कर रहे हैं, तो इसका आमतौर पर मतलब है कि प्रश्न डुप्लिकेट हैं इसलिए उन्हें इस तरह से चिह्नित करें: stackoverflow.com/questions/8473816
केव

3

मैंने सभी परिदृश्यों को संभालने के लिए एक कोटलिन एक्सटेंशन लिखा है जिसके बारे में मैं सोच सकता हूं।

मेरे पास zeroResIdवैकल्पिक है, इसलिए कभी-कभी हम "0 आइटम" के बजाय "नो आइटम" प्रदर्शित करके शून्य को संभालना चाहते हैं।

अंग्रेजी शून्य व्याकरणिक रूप से बहुवचन के रूप में व्यवहार करती है।

जिस स्ट्रिंग का उपयोग करना है उसका चयन केवल व्याकरणिक आवश्यकता के आधार पर किया जाता है।

अंग्रेजी में, शून्य के लिए एक स्ट्रिंग को अनदेखा किया जाता है भले ही मात्रा 0 हो, क्योंकि 0 व्याकरणिक रूप से 2 से अलग नहीं है, या 1 ("शून्य पुस्तकें", "एक पुस्तक", "दो किताबें", और इसी तरह के अलावा अन्य कोई भी संख्या नहीं है) पर)।

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)
    }
}

2

यदि आप डेटा बाइंडिंग का उपयोग कर रहे हैं, तो आप इसके साथ कुछ इस तरह काम कर सकते हैं:

<TextView ... 
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.