How to do an app with truly multilingual strings?

前端 未结 4 1946
渐次进展
渐次进展 2021-02-03 14:34

what should be the best approach to make strings for different languages? I have this problem, I am trying to display strings such as \'month\', \'months\', \'year\', \'years\'.

相关标签:
4条回答
  • 2021-02-03 14:54

    Note that I don't have any android specific experience... but I usually opt for having separate view files for each language i'm going to support, this allows for broader localisation than language alone, you can now also have slightly altered layouts if you know text in some other language can require for example wider buttons, or even different images.

    0 讨论(0)
  • 2021-02-03 14:55

    Thanks to the answers I have got, I am writing 2 Android based solutions. The first one I used was having plurals. At first glance checking the Plurals docs/examples, you could think that there is a quantity="few" (for 2-4 plurals) which checking at the sources only works for locale 'cs'. For the rest of locales, only "one" and "other" are working. So in your strings.xml files:

    <plurals name ="years">
        <item quantity="one">1 year</item>
        <item quantity="other"><xliff:g id="number">%d</xliff:g> years</item>
    </plurals>
    

    So for polish I would have:

    <plurals name ="years">
        <item quantity="one">1 rok</item>
        <item quantity="other"><xliff:g id="number">%d</xliff:g> lat</item>
    </plurals>
    

    Then I would have on my code:

    int n = getYears(...);
    if (Locale.getDefault().getLanguage().equalsIgnoreCase("pl") && n >= 2 && n <= 4) {
       return getString(R.string.years_pl, n);
    } else {
       return getResources().getQuantityString(R.plurals.years, n, n);
    }
    

    And in my strings.xml file for the polish locale I would add the missing string:

    <string name="years_pl"><xliff:g id="number">%d</xliff:g> lata</string>
    

    My second solution has the plurals element for english, spanish, and other languages that don't have too many plural changes. Then for the rest of the languages that have this kind of changes I would use ChoiceFormat. So in my code:

    ...
    private static final int LANG_PL = 0;
    // add more languages here if needed
    ...
    String formats[] = {
    "{0,number} {0,choice,1#" + getString(R.string.year_1) + "|2#" + getString(R.string.years_2_4) +  "|4<" + getString(R.string.years_lots) +"}", // polish
    // more to come
    };
    ...
    // Here I would add more for certain languages
        if (Locale.getDefault().getLanguage().equalsIgnoreCase("pl")) {
           return MessageFormat.format(formats[LANG_PL], n);
        } else {
           return getResources().getQuantityString(R.plurals.years, n, n);
        }
    

    I don't know if these ways are the best way, but for the moment, or until Google makes something better, this works for me.

    0 讨论(0)
  • 2021-02-03 15:01

    Sounds like you want a ChoiceFormat, or at least using one through a MessageFormat:

    public static void main(String... args) {
        String[] formats = { 
            // NOTE - In a real app, you'd fetch the format strings from a language,
            // file, not hard-code them in your program. Obviously.
            "{0,number} {0,choice,0#years|1#year|1<years}", // english
            "{0,number} {0,choice,0#años|1#año|1<años}", // spanish
            "{0,number} {0,choice,1#[fewer than 2]|2#lata|4<lat}", // polish
            "{0,number} år", // swedish - singular and plural forms look the same!
        };
        int[] years = {0, 1, 2, 3, 4, 5, 6};
        for (int year : years) {
            for (String format : formats) {
                System.out.println(MessageFormat.format(format, year));
            }
            System.out.println();
        }
    }
    

    In your program, you would of course get the format string from your string file.

    0 讨论(0)
  • There's a built-in "plurals" support which is not well documented.
    Mentioned here and you can see it in the Browser sources.

    0 讨论(0)
提交回复
热议问题