2010-06-28 11 views
6

quale dovrebbe essere l'approccio migliore per creare stringhe per lingue diverse? Ho questo problema, sto cercando di visualizzare stringhe come "mese", "mesi", "anno", "anni". Attualmente sto lavorando su 3 lingue che conosco: spagnolo, inglese e polacco. Per l'inglese e lo spagnolo questo è semplice. Ma per esempio, negli anni 'lucidati' può diventare 'lata' (dopo i numeri 2 - 4) o 'lat' (dopo i numeri da 5). Stavo pensando di aggiungere una stringa aggiuntiva per questo e renderla vuota nelle altre lingue. Tuttavia questo mi ha fatto pensare alle altre lingue che non conosco, che potrebbero avere ancora più differenze. Quale dovrebbe essere l'approccio migliore in questo caso, se sto pensando di aggiungere più lingue in futuro?Come si fa un'app con stringhe veramente multilingue?

+0

solo per farvi notare spero che stiate lavorando con il file di stringa manifest, alla vostra domanda: si sta riferendo alla situazione erano in fase di esecuzione si sceglie il tuo lang? se è così, penso che la riflessione usando localizion ti aiuterà senza nemmeno chiedere al tuo utente ... –

+0

Sì, sto lavorando con il file delle stringhe. Tuttavia non so se riuscirò a ottenere ciò che voglio in modo pulito usando il file delle stringhe.Sì, si tratta di mostrare determinati messaggi in fase di esecuzione, in particolare si tratta di gestire i plurali, che in alcune lingue possono avere più di 1 modo di scriverli. –

risposta

3

Sembra che si desidera un ChoiceFormat, o almeno utilizzando uno attraverso un 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(); 
    } 
} 

Nel programma, si sarebbe naturalmente ottenere la stringa format dal file stringa.

+0

Grazie per l'esempio, inizialmente stavo cercando una soluzione basata su Android (ad esempio usando solo l'xml per avere le stringhe), quindi a dire il vero ho pensato che non era possibile integrare il sistema di stringhe Android con ChoiceFormat , ma mi hai appena dato una grande idea su come mescolarli entrambi. BTW questo è esattamente quello che volevo, il plurale cambia dopo determinati numeri. L'unica avvertenza, è che l'aggiunta di nuove lingue che hanno modifiche plurali speciali richiederebbe modifiche del codice sorgente. –

+1

Questa non è certamente la strada da percorrere. Avere le tue stringhe nei file di risorse in/res/string. Ma è bene usare ChoiceFormat piuttosto thna plurale perché http://stackoverflow.com/questions/5651902/android-plurals-treatment-of-zero – rds

+0

Per la cronaca, l'esempio di codice qui è solo inteso a mostrare come usare 'ChoiceFormat '. Non suggerisco di dover codificare a fondo le stringhe della lingua. Codice modificato per chiarire – gustafc

0

Nota che non ho alcuna esperienza specifica per Android ... ma di solito scelgo di avere file di visualizzazione separati per ciascuna lingua che sto per supportare, questo consente una localizzazione più ampia della sola lingua, ora puoi anche avere layout leggermente modificati se si conosce che il testo in qualche altra lingua può richiedere ad esempio pulsanti più larghi o anche immagini diverse.

+0

Con Android è possibile farlo. Come si fa con le stringhe che è necessario impostare in fase di runtime? –

+0

Le cose che devo fare al runtime sono abbastanza limitate ma uso una tabella "normale" i18n attraverso alcuni dei miei metodi di classe come 'Stringa :: stringWithLocalizedString ('Good {timeofday} {username}')' e tale che può essere usato con le funzioni di formattazione. – Kris

+0

Oh capisco, grazie! –

1

C'è un supporto "plurals" incorporato che non è ben documentato.
Menzionato here e lo si può vedere nel Browser sources.

+0

Grazie, penso che questo è ciò di cui ho bisogno! Conoscete la differenza tra l'uso di xliff e non? In uno dei link usano questo: % s thing Nell'altro usano: % d corrisponde a

+0

Dopo aver provato questo, non sembra che supporti qualcosa come (ne ho bisogno perché in polacco il plurale per le quantità da 2 a 4 è diverso dal resto) . C'è un modo per ottenerlo? –

+0

Non lo sto utilizzando io stesso, dovrai cercare nelle fonti Android per gli esempi. – yanchenko

2

Grazie alle risposte che ho ricevuto, sto scrivendo 2 soluzioni basate su Android. Il primo che ho usato era avere plurali. A prima vista, verificando i documenti/esempi di Plurals, si potrebbe pensare che ci sia una quantità = "pochi" (per 2-4 plurali) che il controllo su sources funziona solo per le impostazioni locali "cs". Per il resto dei locali, solo "uno" e "altro" funzionano. Così nei file strings.xml:

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

Così per lucidare vorrei avere:

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

allora avrei il mio codice:

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

E nei miei stringhe. file xml per la localizzazione polacca Vorrei aggiungere la stringa mancante:

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

La mia seconda soluzione ha l'elemento plurale per inglese, spagnolo e altre lingue che non presentano troppe modifiche al plurale. Quindi per il resto delle lingue che hanno questo tipo di modifiche userei ChoiceFormat. Quindi, nel mio codice:

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

Non so se questi modi sono il modo migliore, ma per il momento, o fino a quando Google fa qualcosa di meglio, questo funziona per me.

+0

Non capisco davvero perché ti preoccupi di mixare plurali e 'MessageFormat'? Se fossi in te, tenterei di capire come farlo correttamente solo con i plurali, altrimenti abbandonerei i plurali e cercherò semplicemente 'MessageFormat' per tutte le lingue - dicendo qualcosa come' MessageFormat.format (getString (R .string.year_format), n) 'sembra molto più facile di quello che hai ora. – gustafc

+0

Sì, penso che tu abbia ragione, avrò solo MessageFormat. Non volevo buttare via il codice dei plurali. Non posso usare solo plurali (quale sarebbe il migliore). Grazie per l'aiuto :) –

+0

Non usare Plurals. Sono infastiditi. http://stackoverflow.com/questions/5651902/android-plurals-treatment-of-zero – rds