Android >> Spinner dinámico en Android : Provincias y localidades de España

android30pain

Si has creado algún sitio Web, es probable que alguna vez hayas tenido que usar unos elementos llamados comboboxes, estos elementos son listas desplegables que nos permiten seleccionar algún valor. Son muy útiles, ya que al tener que elegir el valor y no introducirlo manualmente, no habrá posibilidad de que el valor sea incorrecto.

Es muy común el uso de comboboxes dinámicos, cuyo funcionamiento es el siguiente: Tenemos un combobox A y otro B, dependiendo del valor seleccionado en A se cargarán unos valores determinados en B. Un ejemplo muy claro es el que vamos a tratar hoy: Se mostrará en el combobox A la listas de provincias españolas, y dependiendo de la provincia seleccionada se cargará la lista de localidades en el combobox B.

Vamos a ver a continuación como implementar este concepto en Android. En primer lugar, especificar que los comboboxes se implementan con la etiqueta <select> en HTML y que en android se utiliza el elemento Spinner.

Vamos a definir los recursos que vamos a utilizar en la aplicación. En primer lugar vamos a mostrar los textos que vamos a usar y que se encuentran almacenados en el fichero strings.xml:

res / values / strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Provincias y Localidades Españolas</string>
    <string name="action_settings">Settings</string>
    <string name="provincia">Provincia</string>
    <string name="localidad">Localidad</string>
    <string name="provincia_prompt">Elija una provincia</string>
    <string name="localidad_prompt">Elija una localidad</string>
    <string name="comprobar">Comprobar</string>
    <string name="message">Ha seleccionado %1$s (%2$s)</string>

</resources>

Luego tendremos el fichero provincias_espana.xml donde se guarda toda la información acerca de las provincias y localidades de España que vamos a usar en la aplicación. En este fichero hay que diferenciar tres partes:

  • El elemento <string-array name="provincias"> : En este array se guardan la lista de provincias españolas por orden alfabético. Es un elemento del tipo String Array.

  • Los elementos <string-array name="localidades_XXXXXX">. Donde XXXXXX se corresponde con el nombre de alguna provincia española. Son elementos del tipo String Array.

  • El elemento <array name="array_provincia_a_localidades">. Este array lo utilizaremos para relacionar cada provincia con sus localidades. Es importante que el par posición/provincia del array array_provincia_a_localidades coincida con el del array provincias. Por ejemplo, la posición 0 del array provincias se corresponde con Albacete, y como podemos ver, la posición 0 del array array_provincia_a_localidades apunta al array localidades_albacete que contiene los nombres de las localidades de Albacete. Es un elemento del tipo Typed Array.

Debido a la longitud del fichero no lo muestra aquí, dejo este enlace al fichero almacenado en mi cuenta de Github.

Una vez definidos los recursos, vamos a ver como implementar los comboboxes. En primer lugar, deberemos definir dos elementos Spinner en nuestro layout, uno para listar las provincias y otra para las localidades:

res / layout / activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tv_provincia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/provincia" />

    <Spinner
        android:id="@+id/sp_provincia"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/provincia_prompt"
        android:spinnerMode="dropdown" />

    <TextView
        android:id="@+id/tv_localidad"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/localidad" />

    <Spinner
        android:id="@+id/sp_localidad"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/localidad_prompt"
        android:spinnerMode="dropdown" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="showLocalidadSelected"
        android:text="@string/comprobar" />

</LinearLayout>

A continuación vamos a ver la manera en la que se van a sincronizar los comboboxes. En primer lugar vamos a definir el método onCreate(Bundle savedInstanceState) de nuestra actividad:

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	this.spProvincias = (Spinner) findViewById(R.id.sp_provincia);
	this.spLocalidades = (Spinner) findViewById(R.id.sp_localidad);

	loadSpinnerProvincias();

}

Como vemos a la hora de crear la actividad invocamos el método loadSpinnerProvincias() que definimos a continuación:

MainActivity.java

/**
 * Populate the Spinner.
 */
private void loadSpinnerProvincias() {

	// Create an ArrayAdapter using the string array and a default spinner
	// layout
	ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
			this, R.array.provincias, android.R.layout.simple_spinner_item);
	// Specify the layout to use when the list of choices appears
	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	// Apply the adapter to the spinner
	this.spProvincias.setAdapter(adapter);

	// This activity implements the AdapterView.OnItemSelectedListener
	this.spProvincias.setOnItemSelectedListener(this);
	this.spLocalidades.setOnItemSelectedListener(this);

}

En primer lugar creamos un Adapter para mostrar la lista de provincias que se encuentra en el array R.array.provincias que hemos definido anteriormente y se lo asignamos al Spinner de provincias. A continuación deberemos hacer que nuestra actividad implemente el interfaz AdapterView.OnItemSelectedListener e implementar el método onItemSelected(AdapterView<?> parent, View view, int pos, long id) y el método onNothingSelected(AdapterView<?> parent) que dejaremos vacío:

public class MainActivity extends Activity implements OnItemSelectedListener {

	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int pos,
			long id) {

		switch (parent.getId()) {
		case R.id.sp_provincia:

			// Retrieves an array
			TypedArray arrayLocalidades = getResources().obtainTypedArray(
					R.array.array_provincia_a_localidades);
			CharSequence[] localidades = arrayLocalidades.getTextArray(pos);
			arrayLocalidades.recycle();

			// Create an ArrayAdapter using the string array and a default
			// spinner layout
			ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
					this, android.R.layout.simple_spinner_item,
					android.R.id.text1, localidades);

			// Specify the layout to use when the list of choices appears
			adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

			// Apply the adapter to the spinner
			this.spLocalidades.setAdapter(adapter);

			break;

		case R.id.sp_localidad:

			break;
		}
	}

	@Override
	public void onNothingSelected(AdapterView<?> parent) {
		// Callback method to be invoked when the selection disappears from this
		// view. The selection can disappear for instance when touch is
		// activated or when the adapter becomes empty.
	}

}

Este método se llamará cuando se selecciona un elemento de alguno de los dos Spinners, ya que lo indicamos en el método onCreate(Bundle savedInstanceState).

Cuando seleccionemos un item de la lista de provincias cargamos el array array_provincia_a_localidades que definimos anteriormente y que como dijimos se encarga de relacionar cada provincia con su lista de localidades, para después cargar la lista de localidades correspondiente a la posición del item seleccionado. La variable pos hace referencia a la posición de la provincia seleccionada en el array de provincias, esta posición debe hacer referencia al array de nombres de localidades de la provincia seleccionada en el array array_provincia_a_localidades. Una vez con la lista de localidades se crea un Adapter y se le asigna al Spinner de localidades. Mostrando por pantalla la lista de localidades.

spinner-espana

Descargar código | GitHub