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 arrayarray_provincia_a_localidades
coincida con el del arrayprovincias
. Por ejemplo, la posición 0 del arrayprovincias
se corresponde con Albacete, y como podemos ver, la posición 0 del arrayarray_provincia_a_localidades
apunta al arraylocalidades_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.