PDA

Ver la Versión Completa : [ SOLUCIONADO ] Cambiar idioma opciones de un Spinner


asuka89
10/11/12, 17:06:35
Hola a todos, soy nueva en esto de programar con Android y me ha surgido una duda.

Estoy haciendo una aplicación Android para mi PFC, he estado siguiendo tutoriales varios y hasta ahora todo bien. La necesito hacer en 3 idiomas, por tanto he creado varios values en la carpeta res (el default en ingles, values-es y values-ca), y en los strings he traducido los textos. El problema es que tengo un spinner con 3 opciones, que lo tengo hecho de esta forma en el MainActivity.java:

spinner1 = (Spinner) findViewById(R.id.spinner1);
String []options={"Light","Moderate","Heavy"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, opciones);
spinner1.setAdapter(adapter);

Al estar en el MainActivity no puedo usar los strings para cambiar el idioma de esas tres palabras.

Mi duda es si hay alguna solución sencilla para traducir esas opciones o no. He estado buscando temas similares pero no he encontrado la solución. Había pensado en poner un if antes dependiendo del idioma configurado en el terminal, pero no he encontrado como se hae, así que no sé si es posible hacerlo.

Muchísimas gracias ^^

mocelet
10/11/12, 17:43:35
¿Tienes el texto escrito en inglés tal cual en el código?

La forma de hacerlo es obteniendo la String en tiempo real con getString(R.string.loquesea). Así no tienes que comparar con "Light" o "Moderate" sino con la String que te devuelva getString, que ya la saca del fichero de idiomas según el que corresponda.

EDIT: Para concretar, que donde pone...

String []options={"Light","Moderate","Heavy"};

sería un

String []options={getString(R.string.light), getString(R.string.moderate), getString(R.string.heavy)};

EDIT 2: De hecho, hay una forma incluso mejor de hacerlo, que es cargando directamente en el spinner un array de strings definido en strings.xml, pero vamos, si son pocos valores tampoco hay problema.

asuka89
10/11/12, 18:05:59
Muchas gracias, de esa manera parece muy sencillo, voy a probarlo ahora mismo y te digo. Justo ahora lo habia solucionado pero haciendo un lio de programación por cada caso con la sentencia

spinner1 = (Spinner) findViewById(R.id.spinner1);
String locale = java.util.Locale.getDefault().getDisplayName();

if (locale.equals("català")){
String []opciones={"Lleugera","Moderada","Intensa"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, opciones);
spinner1.setAdapter(adapter);
} else if (locale.equals("español")) {
String []opciones={"Ligera","Moderada","Intensa"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, opciones);
spinner1.setAdapter(adapter);;
} else { String []opciones={"Light","Moderate","Heavy"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, opciones);
spinner1.setAdapter(adapter);}

Pero luego para un calculo posterior se me complicaba un montón...

mocelet
10/11/12, 18:21:57
Te tiene que hacer daño a la vista escribir texto en el código Java, el texto siempre en los ficheros de recursos y solo en un sitio.

También tiene que empezar a hacerte daño a la vista muchas líneas de código casi iguales que apenas cambian, normalmente pueden sustituirse por un bucle, que es más fácil de mantener y ocupa menos líneas.

Ánimo con el PFC

asuka89
10/11/12, 18:36:44
Tienes razón, pero al principio con un lenguaje que no se conocen todas sus posibilidades... Pues un poco intentas hacerlo por el cuento de la vieja. Por ejemplo de la manera que había hecho me funcionaba, ahora al haber hecho este cambio, tengo que cambiar en un if lo siguiente:

if (r1.isChecked()==true && selec.equals("light"))

Como le digo en la segunda condición que en vez de la palabra "light", sea el string Light, no sé si me explico, es decir que de igual el idioma en el que esté.

El selec lo tengo definido por:

String selec=spinner1.getSelectedItem().toString();

asuka89
10/11/12, 18:39:58
Tienes razón, pero al principio con un lenguaje que no se conocen todas sus posibilidades... Pues un poco intentas hacerlo por el cuento de la vieja. Por ejemplo de la manera que había hecho me funcionaba, ahora al haber hecho este cambio, tengo que cambiar en un if lo siguiente:

if (r1.isChecked()==true && selec.equals("light"))

Como le digo en la segunda condición que en vez de la palabra "light", sea el string Light, no sé si me explico, es decir que de igual el idioma en el que esté.

El selec lo tengo definido por:

String selec=spinner1.getSelectedItem().toString();

EDITO: Puede ser que sea selec.equals(getString(R.string.light))?

EDIT2: Vale si era como me imaginaba, así funciona perfectamente y me he ahorrado como 20 linias de código, muchas gracias ;).

Celtium
10/11/12, 23:11:55
Eso "no" esta bien. La forma oficial de hacerlo es fuera de código y dejar al sistema que lo haga solo.

Primero vamos a crear los string que necesita tu array:

Vamos a res/values/string.xml

Ponemos los string que queremos, por codigo seria:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="str_nosexo">Sin sexo</string>
<string name="str_masculino">Masculino</string>
<string name="str_femenino">Femenino</string>
</resources>

Ahora hacemos el array, te vas a:

res/values/ y alli creas un xml que será llamado arrays.xml En el vas a crear todos los arrays de tu app.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name="sexo">
<item>@string/str_nosexo</item>
<item>@string/str_masculino</item>
<item>@string/str_femenino</item>
</string-array>
</resources>

Como ves este array esta llamando a strings que están definidos fuera del código de la activity. str_nosexo, str_masculino, str_femenino.

ok, ya tenemos un array en el sistema, como lo llamas desde el código? y lo metemos en un Spinner?

Spinner spinner = (Spinner) findViewById(R.id.Spinner_sexo);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this, R.array.sexo, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.s imple_spinner_dropdown_item);
spinner.setAdapter(adapter);

Así ya tenemos el array en el adapter y en el spinner.

Este código te ayuda a tener todo ordenado y limpito. Ordenado por que cuando tengas que cambiar masculino por varon te vas a la carpeta res y cambias alli. Se cambiaran todas funciones que usen ese string y a su vez las que usen el array de un golpe.

Esta manera de plantear el orden vale para muchas cosas y una de ellas es el tratamiento de idiomas. Android se puede ejecutar en español pero también en (por ejemplo) ingles. Para facilitar el cambio de idioma nos dicen que hagamos:

en la carpeta res podemos (ya tenemos la carpeta values) hacer otra carpeta llamada values-en, dentro de ella pondremos las mismas variables con los mismos nombres (importante, mismos nombres) pero con los valores traducidos. es decir;

res/values-en/ y alli creas un xml que sera llamado string.xml en el vas a crear todos los string de tu app que cambien al cambiar de idioma la app a ingles.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="str_nosexo">Prefer Not To Say</string>
<string name="str_masculino">Male</string>
<string name="str_femenino">Female</string>
</resources>

La app reconocerá sólita el idioma en que esta ejecutado Android. Primero buscara los valores de las variables en la carpeta res/ dentro de la subcarperta de ese idioma (por ejemplo values-en). Si no la encuentra la ira a la carpeta generica (res/values).

En el código de la activity no haces nada, ya estas referenciando las variables al puntero R.array.sexo, la app sabe donde buscar.

Suerte ;)

Celtium
11/11/12, 03:43:15
sobre como controlar lo que marca? Pues solamente con un listener ya se soluciona, nos da varios vaores, el selectedItemPosition es el valor de la posición que pulso. No recuerdo si empieza en 0 o en 1.

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View itemSelected, int selectedItemPosition, long selectedId) {
TU CODIGO!!!!!!!!!!!!!!
}
public void onNothingSelected(AdapterView<?> parent) {
}
});

Así no depende de lo que este escrito. Solo tendrás que saber que en la posición 0 esta el string str_nosexo, en la 1 el string str_masculino y en la 2 el string str_femenino, independientemente del idioma.

Aunque hagas la app en 15 idiomas el código de la activity no cambia.

:-)