Programación Android, cómo usar un Spinner II

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0

En la anterior entrada dimos los primeros pasos en el uso del Spinner en Android, añadiendo las opciones que queríamos que se incluyeran en él y quedamos a falta de ver cómo gestionar la opción elegida del Spinner.

Creando las descripciones

En primer lugar vamos a crear una nueva variable, que va a incluir las descripciones de los animales. Para ello vamos a usar un TreeMap, que contendrá como clave el nombre del animal, y como valor su descripción:

private TreeMap<String, String> descrip;

Y creamos un método que va a rellenar los datos de la variable:

public void rellenarDescripciones() {
	// Inicializamos la variable.
	descrip = new TreeMap<String, String>();

	// Rellenamos la variable con las descripciones.
	descrip.put(
		"Perro",
		"Mamífero carnívoro de la familia de los cánidos, doméstico, con cuatro patas, un olfato muy fino y de gran diversidad de tamaños, formas y pelajes, que sirve al ser humano como animal de compañía o para cazar.");
	descrip.put(
		"Gato",
		" Mamífero carnívoro doméstico, de la familia de los félidos, de patas cortas y uñas retráctiles, cabeza redonda, y pelo espeso y suave; suele tenerse como animal de compañía: el gato es un hábil cazador de ratones.");
	descrip.put(
		"Caballo",
		"Mamífero équido, macho, de cuerpo fuerte, orejas pequeñas, cola cubierta de largo pelo y patas terminadas en casco; es herbívoro, se domestica con facilidad y se suele usar para montar en él.");
	descrip.put(
		"Canario",
		"Pájaro de plumaje amarillo, verdoso o casi blanco, muy apreciado por su canto y que se suele criar como ave doméstica.");
	descrip.put(
			"Vaca",
			"Hembra del toro. De joven se denomina ternera, becerra, vaquilla o novilla. Su leche constituye un alimento completísimo y, después de la de burra, es la más parecida a la de la mujer.");
	descrip.put(
		"Cerdo",
		"Mamífero doméstico de cuerpo grueso, patas cortas, cabeza grande, orejas caídas, hocico chato y casi cilíndrico y cola en forma de hélice, que se cría para aprovechar su carne.");
}

Creando el Listener

Ahora en el método onCreate de nuestra Activity lo primero que haremos será la llamada al método que rellenará los datos, para tenerlos listos una vez que seleccionemos una opción del Spinner. Por último tendremos que codificar la lógica que se ejecutará cuando se realice la selección de una de las opciones. Esto se hace utilizando el método spAnimals.setOnItemSelectedListener(listener), que recibe un listener del tipo AdapterView.OnItemSelectedListener.

Para establecer este nuevo listener podemos hacerlo de dos maneras, una de ellas es haciendo que nuestra clase (en este caso sería la propia Activity) implemente el interfaz OnItemSelectedListener, para ello tendríamos que cambiar la cabecera de la clase por:


public class Main extends Activity implements OnItemSelectedListener {

Y posteriormente sobreescribiendo los métodos onItemSelected y onNothingSelected:


@Override
public void onItemSelected(AdapterView<?> adapter, View view, int position,
		long id) {
	// Aquí se codifica la lógica que se ejecutará al seleccionar un elemento del Spinner.
}

@Override
public void onNothingSelected(AdapterView<?> adapter) {

}

Y por último en la llamada al método spAnimals.setOnItemSelectedListener(listener) el parámetro que pasaremos será “this”, con lo que indicaremos que el listener que pasamos es la propia clase:


spAnimals.setOnItemSelectedListeher(this);

La segunda forma sería pasando el listener de forma anónima, de manera que como parámetro al método le pasaríamos un nuevo listener:


spAnimals.setOnItemSelectedListener(new OnItemSelectedListener() {

	@Override
	public void onItemSelected(AdapterView<?> adapter, View vies,
			int position, long id) {
		// Aquí se codifica la lógica que se ejecutará al seleccionar un elemento del Spinner.
	}

	@Override
	public void onNothingSelected(AdapterView<?> adapter) {

	}
});

Cada uno puede seleccionar la forma que le resulte más cómoda, aunque en este ejemplo lo haremos implementando la interfaz, de manera que el código quede más organizado.

Mostrando la descripción

Lo último que nos queda por hacer es mostrar la descripción del animal seleccionado en el EditText, para eso, como ya hemos dicho, utilizaremos el método onItemSelected() del listener. Como vemos en la firma del método, entre los parámetros que recibimos se encuentra la posición del item seleccionado, por lo que sólo tendríamos que recoger la opción seleccionada de nuestro String[] names, a partir de ahí recuperar la descripción del animal y mostrarla en el EditText. Pero recordemos que aún no hemos declarado la referencia al EditText para poder añadirle el texto, por lo que en primer lugar declararemos la variable del EditText y la inicializaremos:


private EditText etDescrip;

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

	etDescrip = (EditText)findViewById(R.id.etDescription);
	// ...
}

Y ya podemos añadirle la descripción que obtengamos del animal:

@Override
public void onItemSelected(AdapterView<?> adapter, View view, int position,
		long id) {
	String name = names[position];
	String description = descrip.get(name);

	etDescrip.setText(description);
}

Y con esto, al seleccionar una opción quedaría así:

Captura
Captura

Descargas

Puedes ver el resultado del ejemplo en tu móvil descargando nuestra aplicación desde Google Play.

Puedes acceder a nuestro repositorio para bajar el proyecto aquí.

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
The following two tabs change content below.
Reborn as IT Developer. Desarrollador Android y fundador de Proyecto Simio. "En realidad, yo no puedo enseñar nada a nadie, sólo puedo hacerles pensar." - Sócrates.

28 thoughts on “Programación Android, cómo usar un Spinner II

  1. Hola,
    quisiera ver si me puedes ayudar. Tengo un php con una consulta mysql que trae regiones de un pais en forma de lista y luego lo codifico a Json con el json_encode($array);. Todo funciona bien desde php incluso rectificando la info que tiene el array con var_dump($array);.

    en el java tengo instanciado mi inputstream con la direccion (en este caso, local a traves de xampp) , lo que no entiendo es como recibo el array en formato Json desde php y como lo inserto en un spinner.

    desde ya gracias por la info.

  2. Una enorme duda….. se puede utilizar un espinner para pasar a otro activity?(si es asi me gustaria un poco de ayuda)

  3. Hola Muchas gracias por compartir tu información.
    Actualmente estoy trabajando con Android Studio y soy nuevo en esto, quisiera saber como puedo capturar el texto del spinner es decir que cuando yo seleccione una opción del spinner esa opción la pueda guardar para posteriormente enviarla a una base de datos.

    Lo estoy buscando asi:

    desAgenda = (Spinner) findViewById(R.id.pysDescripAgenda);

    en un método json:

    private void getpysAgenda(JSONArray j){
    //Traversing through all the items in the json array
    for(int i=0;i<j.length();i++){
    try {
    //Getting json object
    JSONObject json = j.getJSONObject(i);

    //Añadir el nombre del pys que esta en el arraylist
    pysAgenda.add(json.getString(Config.TAG_DESAGENDA));

    } catch (JSONException e) {
    e.printStackTrace();
    }
    }

    //Setting adapter to show the items in the spinner
    desAgenda.setAdapter(new ArrayAdapter(Agendamiento.this, android.R.layout.simple_spinner_dropdown_item, pysAgenda));

    }

  4. Hola IAvilaE, tengo implementado un spinner desde SQLite y al querer acceder al contenido seleccionado me aparece el mensaje de:”android.database.sqlite.SQLiteCursor@…”, ¿alguna sugerencia de como resolverlo?

    spAlimento = (Spinner) findViewById(R.id.sp_alimento);

    //Abrimos la base de datos
    DatabaseHelper admin_SpAlimentos = new DatabaseHelper(this);
    SQLiteDatabase bd_SpAlimentos = admin_SpAlimentos.getWritableDatabase();

    //Creamos el Cursor
    Cursor curAlimentos= bd_SpAlimentos.rawQuery(“select _id as _id, ALIMENTOS from DataBase where CLASIFICACION= “+'”‘+”Cereales”+'”‘,null);

    if (curAlimentos.moveToFirst()){
    startManagingCursor(curAlimentos);
    String[] fromAlimentos= new String[]{“ALIMENTOS”};
    int[]toAlimentos=new int[]{android.R.id.text1};

    //Creamos el adaptador
    SimpleCursorAdapter adapterAlimentos=new SimpleCursorAdapter(this,android.R.layout.simple_spinner_item, curAlimentos, fromAlimentos, toAlimentos);

    //Añadimos el Layout para el Menu
    adapterAlimentos.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    //Le indicamos al spinner el adaptador a usar
    spAlimento.setAdapter(adapterAlimentos);
    }
    else{
    Toast.makeText(this, “No existe Valor”,Toast.LENGTH_SHORT).show();}

    //Escuchador spAlimento
    spAlimento.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView parent, View selectedItemView, int position, long id) {

    Toast.makeText(parent.getContext(), parent.getItemAtPosition(position).toString(),
    Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNothingSelected(AdapterView parent) {

    }
    });

    1. Buenas Pedro,

      Realmente con esta información poco puedo saber, tendrás que prestar atención a en qué linea está fallando y el por qué. Debugueando el código podrás obtener más información que te ayudará a encontrar el error.

      Un saludo :)

  5. Hola, buenas, me gusto mucho la información me fue de utilidad, tengo una consulta, puede estar un poco salida del tema, ¿como se podrían introducir dos spinners en un solo activity? El introducir el código del primer spinner si funciona correcta mente, pero al momento de agregar el segundo, no se si lo tengo que hacer en el mismo lugar donde lo hice con el primero o en una parte diferente.
    Gracias, cualquier ayuda es bienvenida.

    1. Buenas Andrea,

      No se si he entendido bien tu pregunta, pero supongo que te refieres a declarar diferentes spinners en tu Activity para poder usarlos. Si te refieres a esto, por norma se suelen declarar todas las variables que utilices al principio de la clase, para tener el código organizado y saber siempre dónde se ha declarado todo. Eso quiere decir que en el mismo punto en el que declaras tu primer Spinner, deberías declarar los demás que puedas usar (no es obligatorio, pero sí muy recomendable), podrías hacerlo así:
      private Spinner spinner1, spinner2;

      Después la inicialización sería la misma que con el primer spinner y que con el resto de controles, en el método onCreate de la Activity:
      spinner1 = (Spinner) findViewByID(R.id.spinner1);
      spinner2 = (Spinner) findViewByID(R.id.spinner2);

      Y la utilización también sería exactamente igual para cada uno de los spinners, añadir un adaptador para inyectar datos, o hacerlo desde xml utilizando la propiedad android:entries, añadir los listeners a cada spinner para saber cuándo se selecciona un valor del spinner, leer los valores seleccionados, etc.

      Lo único a tener en cuenta es que si el listener está implementado en la activity y a ambos spinners les haces setListener(this) en el método que has implementado para ese listener tendrás que identificar quien ha llamado al método (qué spinner ejecuta el listener). Para hacer esto basta con utilizar un switch que evalue el ID del objeto que recibe el listener:
      switch(view.getID){
      case R.id.spinner1:
      // código
      break;
      case R.id.spinner2:
      // código
      break;
      }

      Espero haber aclarado tus dudas :)
      Un saludo.

  6. Buenas Tardes, muy bueno el tuto gracias, tengo una consulta no se si este salida de tema aqui pero si me pudiera ayudar se lo agradeceria muchisimo, yo creo el spinner y lo cargo con Strings de un array y en el emulador corre bien, lo que pasa es que el logcat muestra un mensaje parecido a este could not find class android.support.v7.widget. from android.support.v7 etc, la v7 y v4 .jar ya estan referenciadas en el proyecto pero ni la menos idea por que sale esto, lo otros es que en el emulador ignora el error y el spinner carga los datos bien pero al generar la apk e instalarla en algun dispositivo se crashea al tratar de cargar el contido del Spinner

    1. Buenas Alexis, gracias por el comentario :)

      Pues la verdad es que no sabría decirte cómo arreglarlo, nunca vi un problema como ese. Se me ocurre que puedas tener algún tipo de incompatibilidad al usar esa librería, pero es extraño porque yo ya las he usado en bastantes ocasiones y nunca me dio un problema así.

      En cualquier caso, no sé cómo tendrás hecho el proyecto, pero si sólo es para usar un Spinner, no necesitas ninguna compatibilidad, podrías eliminar los import que llamen a esas librerías y utilizar los import normales (por ejemplo usar android.app.Fragment en lugar de app.support.v4.app.Fragment), pero esto lo tendrás que valorar tú en función a lo que realmente tenga que hacer tu programa y en qué dispositivos quieras que funcione.

      Siento no poder ayudarte más, un saludo.

    1. Sí, sin problemas. Sólo tendrías que buscar la lógica para hacerlo. Por ejemplo si tienes la imagen como recurso en la carpeta drawable almacenas un int (en lugar del string de descripción) que se refiera al id del drawable y luego sólo tendrás que recuperar el drawable a partir de ese id, pero si es un recurso que está en internet almacenarías por ejemplo una ruta para descargar la imagen.

      Todo va a depender de lo que tú necesites, pero ten en cuenta que en el map podrás almacenar lo que necesites almacenar.

  7. Consulta:
    en el ejemplo ya sale seleccionado el primer item sin necesidad de clickear en el, Pero si no necesito que aparesca preseleccionado el primero?
    la cuestion es que tengo 3 spinner el contenido del segundo depende de lo que seleccione el el primero y asi sucesivamente, Pero la carga de los datos no se detiene, es como si entrase en un bucle en el onItemSelected. dentro de este uso un case para identificar de cual spinner viene el evento.
    cualquier ayuda sera bienbenida. Gracias

      1. Gracias IAvilaE por tu tiempo. ya funciona correctamente.
        consulta: talves algo desviada del tema. tienen algun tutorial para enviar una coleccion de datos al WS? solo ecuentro envios de un solo objeto. Persona animale ETC. pero en mi caso devo enviar varios objetos VENTAS en un array supongo. ProductoId y cantidad.
        Gracias.

        1. Puedes convertir tus objetos (que pueden contener colecciones) a JSON, para posteriormente mandar ese JSON al servidor y analizarlo. Para hacerlo de una forma fácil tienes una librería creada por Google, GSon, que convierte automáticamente tus clases Java a String, con formato JSON (y también leer un documento JSON y parsearlo a un objeto en Java). El próximo tutorial que publiquemos será precisamente sobre el uso de esta librería.

          Un saludo.

Deja un comentario