Cómo obtener elementos seleccionados de la vista de lista de selección múltiple
Estoy utilizando un adaptador de matriz y para esto estoy añadiendo una lista de matriz de cadena s, la lista es multi seleccionar, ¿Cómo puedo obtener los valores de los elementos de la lista se hace clic?
my_contacts_list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,conts_list); my_contacts_list.setAdapter(adapter);
Yo estaba tratando de hacer esto,
- Java.lang.NullPointerException: Intenta invocar el método virtual 'int android.view.View.getImportantForAccessibility ()' en una referencia de objeto nulo
- ¿Por qué mi onItemSelectedListener no se llama en un ListView?
- ¿Cómo abrir una nueva actividad haciendo clic en un elemento de listview?
- Android: Mostrar la imagen en la vista de imagen por SimpleAdapter
- FastScrollBar salir de la pantalla, cuando SectionIndexer implementado
SparseBooleanArray positions = my_contacts_list.getCheckedItemPositions(); int size=positions.size(); int i=0; while(i <= size){ conts_list.get(positions.get(i)); i++; }
Pero position.get (i) es una lista de matrices, ¿cómo recuperar los elementos seleccionados entonces?
- BaseAdapter: set hasStableIds () a false?
- El evento Onclick se realiza incluso con un clic largo
- Sincronizar 2 ListViews desplazándose
- El dedo de desplazamiento rápido desaparece mientras se desplaza AlphabetIndexer
- Deslice la animación expandida en android
- Reutilización de vistas en Android Listview con 2 diseños diferentes
- Creando un appwidget android ListView for SDK 8?
- Cómo mostrar el encabezado de ListView cuando está vacío
SparseBooleanArray.get devuelve un booleano, pero creo que necesitas comprobarlo para cada posición en tu lista, por ejemplo
int len = listView.getCount(); SparseBooleanArray checked = listView.getCheckedItemPositions(); for (int i = 0; i < len; i++) if (checked.get(i)) { String item = cont_list.get(i); /* do whatever you want with the checked item */ }
Esta API es un desastre. Esto es lo que funciona para mí.
SparseBooleanArray checked = tags.getCheckedItemPositions(); for (int i = 0; i < checked.size(); i++) { if(checked.valueAt(i) == true) { Tag tag = (Tag) tags.getItemAtPosition(checked.keyAt(i)); Log.i("xxxx", i + " " + tag); } }
Creo que la forma más rápida de obtener la información de este SparseArray
es iterar sobre las claves (en realidad estoy bastante seguro de que las soluciones anteriores no funcionarán en todos los casos). El ListView
introducirá un par (índice, true) en el SparseBooleanArray
para cada índice seleccionado.
Así que el código podría verse así:
SparseBooleanArray checked = lv.getCheckedItemPositions(); int size = checked.size(); // number of name-value pairs in the array for (int i = 0; i < size; i++) { int key = checked.keyAt(i); boolean value = checked.get(key); if (value) doSomethingWithSelectedIndex(key); }
Creo que la respuesta de Daren Robbins es incorrecta, aquí está mi respuesta:
ArrayList<String> ids = extras.getStringArrayList("commonids"); SparseBooleanArray checked = lv.getCheckedItemPositions(); for (int i = 0; i < checked.size(); i++) { if(checked.get(i)) Log.i("CheckedItem", ids.get(checked.indexOfKey(i))); }
Asumir ids es un arraylist con el mismo tamaño de la lista que contiene los ids de los elementos en la vista de lista
La cosa es que debe iterar todos los elementos de vista de lista, pero no checkedPositions.
Defina las variables:
- ListView (La instancia de usted ListView)
- Nombres (el ArrayList que usted es)
-
SaveCheckedName (guardar todo el nombre registrado en este Arraylist)
SparseBooleanArray checkedPositions = listView.getCheckedItemPositions(); for (int i = 0; i < subjectListView.getCount(); i++) { if (checkedPositions.get(i) == true) { saveCheckedName.add(names.get(i)); } }
Al igual que muchas otras cosas, ListView
s multi-select es un problema real en Android.
En lugar de simplemente solicitar los elementos seleccionados como una List
de Object
s (querido Google, esto es lo que esperamos):
List selected_items = my_list_view.getSelectedItems();
Nos vemos obligados a usar esta estupendamente ridícula API:
SparseBooleanArray checked = my_list_view.getCheckedItemPositions(); int num_selected = 0; for(int i = 0; i < checked.size(); i++) { if(checked.valueAt(i)) { num_selected++; int key = checked.keyAt(i); boolean value = checked.get(key); if (value) { // } } }
El horriblemente llamado SparseBooleanArray
se llena llamando al getCheckedItemPositions()
aún más horriblemente llamado en ListView
. Pero en lugar de devolver las posiciones de cada elemento seleccionado / seleccionado en la lista, devuelve la posición de cada elemento de la lista que fue tocado, si actualmente está realmente seleccionado o no. Increíble, pero cierto.
Para calcular si el elemento está ACTUALMENTE ACTUALMENTE revisado, nos vemos obligados a probar el valueAt(i)
para la veracidad mientras hacemos un bucle a través de la serie de elementos "siempre tocada".
Además de esta locura, si queremos calcular el número de elementos seleccionados, parecemos forzados a incrementar nuestro propio contador (por ejemplo, num_selected
).
Con API como esta, es una maravilla poco los desarrolladores son un montón enojado!
CÓMO SOLUCIONE EL PROBLEMA con un segundo ArrayList:
- Creó una segunda instancia de ArrayList
- Ha actualizado la instancia de ArrayList con los elementos UNCHECKED
-
Lo agregó a mi listadapter
public void removeSelectedItems(){ updatedList = new ArrayList<String>(); //initialize the second ArrayList int count = lv.getCount(); //number of my ListView items SparseBooleanArray checkedItemPositions = getListView().getCheckedItemPositions(); for (int i=0;i < count;i++){ if(!checkedItemPositions.get(i)) updatedList.add(liveNames.get(i)); //liveNames is the current ArrayList Log.e("TEST", liveNames.get(i)); } adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, updatedList); setListAdapter(adapter);}
Espero que sea útil 🙂
Foo objectAtCheckedRow = null; for (int i = 0; i < positions.size(); i++) { //positions.size() == 2 objectAtCheckedRow = adapter.getItem(positions.keyAt(i)); //Do something significant with object here }
Un par de cosas para entender
- Es una lista de pares clave-valor.
- La clave es el índice de una fila, get it with positions.keyAt (i)
- El valor es si la fila en ese índice está marcada o no (true o false), consígala con positions.valueAt (i)
- Positions.get (i) devuelve el mismo booleano que .valueAt (i)
- Cuidado de no mezclar los índices. Usted no necesita ( y no debe ) iterar sobre su lista entera. Utilice int i para iterar sobre posiciones, pero no use i para obtener objetos de su lista
- Pero en este caso específico (listView.getCheckedPositions ()) sólo se rellena en true (filas seleccionadas), por lo que en realidad no es necesario verificar utilizando .get (i) ni .valueAt (i)
Ejemplo: Digamos que ha comprobado los puntos 5 y 8 de la lista (índice 4 y 7), entonces positions.size () == 2 y yo seremos 0 y luego 1
Así que cuando:
I == 0 entonces keyAt (i) == 4
I == 1 entonces keyAt (i) == 7
I == 0 OR i == 1 entonces valueAt (i) == true Y obtiene (i) == true
Usamos esto en nuestra clase de utilidad de Android. Los genéricos ayudan a prevenir las advertencias del compilador, pero puede quitarlas si el adaptador devuelve varios tipos.
public static <T> Collection<T> getCheckedItems(ListView listView) { Collection<T> ret = new ArrayList(); SparseBooleanArray checkedItemPositions = listView.getCheckedItemPositions(); for (int i = 0; i < checkedItemPositions.size(); i++) { if (checkedItemPositions.valueAt(i)) { T item = (T) listView.getAdapter().getItem(checkedItemPositions.keyAt(i)); ret.add(item); } } return ret; }
Creo que otra opción es simplemente hacer un seguimiento de todo esto usted mismo.
list.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> listView, View selectedItem, int position, long itemId) { //Keep a reference here, and toggle a global variable.
FYI, Así es como Google lo hizo:
Extraído de http://mytracks.googlecode.com/hg/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java
/** * Gets the checked positions in a list view. * * @param list the list view */ private int[] getCheckedPositions(ListView list) { SparseBooleanArray positions = list.getCheckedItemPositions(); ArrayList<Integer> arrayList = new ArrayList<Integer>(); for (int i = 0; i < positions.size(); i++) { int key = positions.keyAt(i); if (positions.valueAt(i)) { arrayList.add(key); } } int[] result = new int[arrayList.size()]; for (int i = 0; i < arrayList.size(); i++) { result[i] = arrayList.get(i); } return result; }
Y aquí está mi versión adaptada:
public static List<Integer> getAbsListViewCheckedItemPositions(AbsListView absListView) { SparseBooleanArray checked = absListView.getCheckedItemPositions(); List<Integer> positions = new ArrayList<>(); int checkedSize = checked.size(); for (int i = 0; i < checkedSize; i++) { if (checked.valueAt(i)) { positions.add(checked.keyAt(i)); } } return positions; }
- La mejor manera de obtener la ubicación del GPS del usuario en segundo plano en Android
- Honeycomb Android emulador es perro lento – se manejará antes del lanzamiento oficial?