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.