Android Spinner con opción múltiple

¿Cómo creo spinner que permite elegir varios elementos, es decir, spinner con casillas de verificación?

He escrito la implementación personalizada de MultiSpinner. Se ve similar a la ruleta normal, pero tiene casillas de verificación en lugar de botones de radio. Los valores seleccionados se muestran en la ruleta divididos por comas. Todos los valores están marcados por defecto. Intentalo:

 package cz.destil.settleup.gui; public class MultiSpinner extends Spinner implements OnMultiChoiceClickListener, OnCancelListener { private List items; private boolean[] selected; private String defaultText; private MultiSpinnerListener listener; public MultiSpinner(Context context) { super(context); } public MultiSpinner(Context arg0, AttributeSet arg1) { super(arg0, arg1); } public MultiSpinner(Context arg0, AttributeSet arg1, int arg2) { super(arg0, arg1, arg2); } @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { if (isChecked) selected[which] = true; else selected[which] = false; } @Override public void onCancel(DialogInterface dialog) { // refresh text on spinner StringBuffer spinnerBuffer = new StringBuffer(); boolean someUnselected = false; for (int i = 0; i < items.size(); i++) { if (selected[i] == true) { spinnerBuffer.append(items.get(i)); spinnerBuffer.append(", "); } else { someUnselected = true; } } String spinnerText; if (someUnselected) { spinnerText = spinnerBuffer.toString(); if (spinnerText.length() > 2) spinnerText = spinnerText.substring(0, spinnerText.length() - 2); } else { spinnerText = defaultText; } ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerText }); setAdapter(adapter); listener.onItemsSelected(selected); } @Override public boolean performClick() { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setMultiChoiceItems( items.toArray(new CharSequence[items.size()]), selected, this); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.setOnCancelListener(this); builder.show(); return true; } public void setItems(List items, String allText, MultiSpinnerListener listener) { this.items = items; this.defaultText = allText; this.listener = listener; // all selected by default selected = new boolean[items.size()]; for (int i = 0; i < selected.length; i++) selected[i] = true; // all text on the spinner ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, new String[] { allText }); setAdapter(adapter); } public interface MultiSpinnerListener { public void onItemsSelected(boolean[] selected); } } 

Lo usas en XML así:

  

Y le pasas datos en Java así:

 MultiSpinner multiSpinner = (MultiSpinner) findViewById(R.id.multi_spinner); multiSpinner.setItems(items, getString(R.string.for_all), this); 

También necesita implementar el oyente, que devolverá la misma matriz de longitud, con verdadero o falso para mostrar seleccionado a no seleccionado.

 public void onItemsSelected(boolean[] selected); 

Solo me gustaría mostrar una versión alternativa de MultiSpinner de @ Destil (gracias por su código inspirador) que permite usar “entradas android:” en xml, como un girador.

Inicialmente, no muestra un texto predeterminado, como “elegir uno”, pero puede obtenerlo fácilmente configurando un ArrayAdapter adicional en el constructor.

MultiSpinner.java

 package com.example.helloworld; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnMultiChoiceClickListener; import android.content.res.TypedArray; import android.util.AttributeSet; import android.widget.ArrayAdapter; import android.widget.Spinner; /** * Inspired by: http://stackoverflow.com/a/6022474/1521064 */ public class MultiSpinner extends Spinner { private CharSequence[] entries; private boolean[] selected; private MultiSpinnerListener listener; public MultiSpinner(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiSpinner); entries = a.getTextArray(R.styleable.MultiSpinner_android_entries); if (entries != null) { selected = new boolean[entries.length]; // false-filled by default } a.recycle(); } private OnMultiChoiceClickListener mOnMultiChoiceClickListener = new OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { selected[which] = isChecked; } }; private DialogInterface.OnClickListener mOnClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // build new spinner text & delimiter management StringBuffer spinnerBuffer = new StringBuffer(); for (int i = 0; i < entries.length; i++) { if (selected[i]) { spinnerBuffer.append(entries[i]); spinnerBuffer.append(", "); } } // Remove trailing comma if (spinnerBuffer.length() > 2) { spinnerBuffer.setLength(spinnerBuffer.length() - 2); } // display new text ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerBuffer.toString() }); setAdapter(adapter); if (listener != null) { listener.onItemsSelected(selected); } // hide dialog dialog.dismiss(); } }; @Override public boolean performClick() { new AlertDialog.Builder(getContext()) .setMultiChoiceItems(entries, selected, mOnMultiChoiceClickListener) .setPositiveButton(android.R.string.ok, mOnClickListener) .show(); return true; } public void setMultiSpinnerListener(MultiSpinnerListener listener) { this.listener = listener; } public interface MultiSpinnerListener { public void onItemsSelected(boolean[] selected); } } 

attrs.xml

       

layout_main_activity.xml

  

Hasta donde yo sé, Spinner no tiene un modo de elección múltiple. En su lugar, puede crear un ImageButton y establecer una flecha hacia abajo ImageButton en el lado derecho y en el evento click puede abrir un Dialog con elementos con múltiples casillas de verificación.

Consulte aquí: Diálogos de selección múltiple de Android

¡Gracias por la publicacion! Gran solución Hice un pequeño cambio en la clase (method setItems) para permitir a los usuarios establecer elementos ya seleccionados en lugar de seleccionar todos los elementos en true de manera predeterminada.

 public void setItems( List items, List itemValues, String selectedList, String allText, MultiSpinnerListener listener) { this.items = items; this.defaultText = allText; this.listener = listener; String spinnerText = allText; // Set false by default selected = new boolean[itemValues.size()]; for (int j = 0; j < itemValues.size(); j++) selected[j] = false; if (selectedList != null) { spinnerText = ""; // Extract selected items String[] selectedItems = selectedList.trim().split(","); // Set selected items to true for (int i = 0; i < selectedItems.length; i++) for (int j = 0; j < itemValues.size(); j++) if (selectedItems[i].trim().equals(itemValues.get(j))) { selected[j] = true; spinnerText += (spinnerText.equals("")?"":", ") + items.get(j); break; } } // Text for the spinner ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerText }); setAdapter(adapter); }