Para controlar cuando un
elemento del Spinner es seleccionado existe el método onItemSelected(),
semejante al onClick() que vimos para los RadioButton o los Button. Por cierto,
entre los atributos XML de la definición de un Spinner podeis comprobar que
existe un onClick en el que teóricamente podríamos definir el método a ejecutar
pero da un error de ejecución (al menos yo no he sido capaz de hacerlo funcionar).
Para implementar el método
onItemSelected hay que definir un listener y asociarlo al Spinner de la
siguiente forma:
public class PruebaSpinner2Activity extends Activity {
String[] paises = { "Ninguno", "Alemania", "Argentina",
"Brasil", "España", "Francia",
"Italia", "Mexico", "Peru"};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner spPaises = (Spinner) findViewById (R.id.spinner);
// Defino el adaptador para el Spinner
ArrayAdapter<String> aa_paises = new ArrayAdapter<String>
(this, android.R.layout.simple_spinner_item, paises);
// Asigno el adaptador al
Spinner
spPaises.setAdapter(aa_paises);
// Asigno el listener al Spinner
spPaises.setOnItemSelectedListener(new SpinnerListener());
}
// Denificion del listener
public class SpinnerListener
implements OnItemSelectedListener {
// Metodo onItemSelected en
el que indicamos lo que queremos hacer
// cuando sea seleccionado un elemento
del Spinner
public void
onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
TextView resultado = (TextView)
findViewById (R.id.resultado);
// Cargo en un TextView
el contenido del elemento seleccionado.
resultado.setText("Ha seleccionado: "+
parent.getItemAtPosition(pos). toString());
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
}
En
la definición del listener se incluyen dos métodos, uno en el que indicamos lo
que queremos hacer cuando sea seleccionado un elemento del Spinner
(onItemSelected) y otro para cuando no haya ningún elemento seleccionado porque
el adaptador esté vacío (onNothingSelected).
El
resultado:
Cargando Spinners dinámicamente
Puede
ser que se nos dé el caso de que el contenido de un Spinner dependa de la
selección que se haga en otro. En el ejemplo de paises que estamos siguiendo,
imaginemos que tenemos un segundo Spinner con las principales ciudades del país
seleccionado. Logicamente si cambiamos el pais, debemos variar el contenido del
segundo Spinner.
Veamos
cómo podemos solucionarlo:
Fichero
/res/values/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/tv_pais">
</TextView>
<Spinner android:id="@+id/paises"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="@string/sp_paises"
android:entries="@array/arrayPaises">
</Spinner>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/tv_ciudad">
</TextView>
<Spinner android:id="@+id/ciudades"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="@string/sp_ciudades">
</Spinner>
</LinearLayout>
En el fichero xml definimos los dos Spinner pero
sólo utilizo el atributo android:entries en el primero cargando el arrayPaises
que es fijo. El contenido del Spinner ciudades se cargará dinámicamente en
función de la selcción del país.
Fichero /res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="arrayPaises">
<item>Ninguno</item>
<item>España</item>
<item>Francia</item>
<item>Mexico</item>
</string-array>
<string-array name="arrayEspana">
<item>Alicante</item>
<item>Barcelona</item>
<item>Madrid</item>
<item>Sevilla</item>
</string-array>
<string-array name="arrayFrancia">
<item>Burdeos</item>
<item>Paris</item>
<item>Lyon</item>
<item>Marsella</item>
</string-array>
<string-array name="arrayMexico">
<item>Ciudad de Mexico</item>
<item>Guadalajara</item>
<item>Monterrey</item>
<item>Acapulco</item>
</string-array>
<string-array name="arrayDefecto">
<item>--</item>
</string-array>
</resources>
En
nuestro código Java:
public class
PruebaSpinnerActivity extends Activity {
Spinner spCiudades;
ArrayAdapter<CharSequence> aa_espana;
ArrayAdapter<CharSequence> aa_francia;
ArrayAdapter<CharSequence> aa_mexico;
ArrayAdapter<CharSequence>
aa_default;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner
spPaises = (Spinner) findViewById(R.id.paises);
// Asigno
el listener al Spinner de paises
spPaises.setOnItemSelectedListener(new SpinnerListener());
}
public class
SpinnerListener implements OnItemSelectedListener {
public void
onItemSelected(AdapterView<?> parent,
View
view, int pos, long id) {
// Lamo a un método
para cargar el Spinner de ciudades
// pasandole
la posicion del elemento seleccionado en
// el Spinner de paises
cargaSpinnerCiudad(parent.getSelectedItemPosition());
}
public void
onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
// Defino los adaptadores
para cada pais y asigno el que corresponde
private void cargaSpinnerCiudad(int pais){
spCiudades = (Spinner)
findViewById(R.id.ciudades);
aa_espana =
ArrayAdapter.createFromResource
(this, R.array.arrayEspana,
android.R.layout.simple_spinner_item);
aa_francia = ArrayAdapter.createFromResource
(this, R.array.arrayFrancia,
android.R.layout.simple_spinner_item);
aa_mexico = ArrayAdapter.createFromResource
(this, R.array.arrayMexico,
android.R.layout.simple_spinner_item);
aa_default = ArrayAdapter.createFromResource
(this, R.array.arrayDefecto,
android.R.layout.simple_spinner_item);
switch (pais) {
case 1: spCiudades.setAdapter(aa_espana);
break;
case 2: spCiudades.setAdapter(aa_francia);
break;
case 3: spCiudades.setAdapter(aa_mexico);
break;
default: spCiudades.setAdapter(aa_default);
break;
}
}
}
He
definido un adaptador para cada uno de los paises mas uno por defecto por si no
seleccionan ninguno.
Asigno
un listener al Spinner de paises y cada vez que se selecciona un elemento llamo
al método cargaSpinnerCiudad(pais) pasandole como parámetro la posición del
elemento seleccionado en el Spinner de paises con el método
getSelectedItemPosition().
Una
vez conocido el pais asigno al Spiner de ciudades el adaptador correspondiente.
Inicialmente
se carga el Spinner de paises con el arrayPaises y el de ciudades con el
arrayDefault.
Una
vez seleccionado un pais se actualiza el Spinner de ciudades automáticamente.
Espero
que os sea de utilidad.
Hasta
la próxima.
Gracias por el tutorial
ResponderEliminarBuenas tardes, me aparecen una seria de errores al seguirlo paso a paso, tendras el proyecto (codigo) que me puedes facilitar?
ResponderEliminarHola, no suelo guardar el código de los ejemplos del blog, de todas maneras indícame alguno de los errores que te aparecen y procuraré indicarte la solución.
EliminarSaludos.
Buenas noches, excelente tu entrada.. me ayudo muchisimo, pero sigo sin poder hacer algo, tengo 4 spinner y necesito condicionarlos, lo mas parecido a tu ejmplo seria que yo necesito PAIS, CIUDAD, ESTADOS, MUNICIPIOS Y PARROQUIAS, obviamente la seleccion de uno condiciona al siguiente pero no se como hacerlo de ciudad a estado, podrias darme alguna orientacion por favor.
ResponderEliminarHola Kndy, supongamos que queremos añadir un nuevo nivel de Spinner dinamico, es decir, Pais, Ciudad y Estado. Basicamente tendrias que definir un array con los elementos de cada estado en el fichero arrays.xml, despues definir un ArrayAdapter por cada uno de ellos y, por ultimo un Listener para el spinner de ciudades.
EliminarLa clave está en que el método llamado por el listener de ciudades debe recibir dos parámetros, el pais y la ciudad seleccionada y con ellos podremos asignar el adapter correspondiente al estado.
Espero haberte ayudado.
Un saludo y gracias por colaborar.
Hola que tal, me sirve el ejemplo pero, mi caso esta asi, necesito esto de dinamica entre spinner, pero en mi caso desde una base de datos, que al seleccionar el pais, se actualise igual a como en tu ejemplo pero todo desde una base de datos SQLITE teniendo en tablas diferentes cada dato en una tabla los paises en otra los estados..., saludos, espero me puedas ayudar...
EliminarMuchas gracias por compartir tu conocimiento, tengo la siguiente duda, en el case de que quiera guardar el valor del spinner para que cuando vuelva a ingresar me muestre los valores guardados, agradezco si me puedes indicar como se debería hacer. gracias
ResponderEliminarexcelente!!eres un crack
ResponderEliminarcomo hacer que lo que seleccione en el spinner se guarde en una base de datos
ResponderEliminar