09/05/2013
Los literales o textos que mostramos en pantalla y que están predefinidos en la propia aplicación deberían ser ubicados en el fichero /res/values/strings.xml. En el caso de que nuestra aplicación sea multilenguaje tendremos que traducir y crear un fichero strings.xml para cada lenguaje (o lenguaje y región, por ejemplo español de España o español de Argentina).
Lo que haremos es ubicar cada strings.xml en un directorio /res/values- seguido del código ISO-639-1 del idioma y opcionalmente de la región siguiendo el código de país del estándar ISO 3166-1 alpha-2 precedido por una r (lo que no podemos tener es una región sin estar precedida por su idioma). Por ejemplo:
- /res/values-fr/ : francés
- /res/values-es/: español
- /res/values-es-rAR/: español de Argentina
Android seleccionará automáticamente el fichero correspondiente al idioma/región que esté configurado en el sistema operativo, considerando siempre el fichero /res/values/strings.xml como idioma por defecto. Este criterio se aplica tanto a los literales que definamos en los xml (@string\texto) como los utilizados programáticamente (getString(R.string.texto)). Asimismo, Android Lint nos ayuda en esta tarea ya que nos indicará los literales definidos en un strings.xml que falten en cualquier otro para que no se nos «escape» nada en las traducciones.
Los textos pueden ser dinámicos y contener variables a reemplazar en las Activity. Por ejemplo, el siguiente mensaje tiene una variable de tipo cadena y otra de tipo numérico.
<string name="resultados">Resultados para la búsqueda %1$s : %2$d</string>
Las variables se sustituirán utilizando el método format de la clase String estándar de Java.
String msg = String.format(res.getString(R.string.resultados), busqueda, numEncontrados);
En cualquier caso, siempre podemos forzar un Locale por defecto programáticamente para nuestra aplicación en el caso de que dentro de ella podamos definir el idioma a utilizar y obviar por tanto la configuración definida en el propio Android. Esto se puede hacer con el siguiente snippet:
Locale locale = new Locale("en_US"); Locale.setDefault(locale); Configuration config = new Configuration(); config.locale = locale; context.getApplicationContext().getResources().updateConfiguration(config, null);
Si fuera necesario el locale en uso puede ser obtenido programáticamente utilizando la clase Locale, por ejemplo la llamada
Locale.getDefault().getLanguage();
devolverá la cadena «es» para español y «en» para inglés.
Para los valores numéricos, incluyendo divisas, y de fechas, las clases NumberFormat, DecimalFormat y SimpleDateFormat, además de admitir patrones específicos, aplican un formato predefenido para el locale actual pudiéndose además indicar un locale específico.
Por último, un pequeño tip a la hora de utilizar el método getString para obtener cadenas localizadas. Este método recibe el id de la cadena en los ficheros strings.xml, siendo un entero que podemos obtener a partir de las constantes autogeneradas en R. No obstante, si queremos obtener una cadena directamente por su clave podemos obtener su id con la siguiente sentencia:
getResources().getIdentifier(key, "string", getPackageName());