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,
- Buena solución para retener los elementos listview cuando el usuario rote el teléfono y mantenga todos los datos en ArrayAdapter
- Auto oculta el teclado después de desplazarse ListView en android
- CursorAdapter clasificación dinámica
- Android cursorLoader con paginación o carga más funcionalidad?
- Android - eliminar el elemento de ListView en un clic largo
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?
- Ocultar elementos en listview correctamente
- Cómo deshabilitar el elemento ListView después de que se ha hecho clic?
- Cambiar dinámicamente la altura de la fila en una vista de lista basada en el número de elementos de la lista
- ¿Por qué no "notifyDatasetChanged ()" notifica todos los elementos visibles?
- Cómo utilizar Universal Image Loader
- Actualizar Android ListActivity cuando cambia los datos de la lista?
- No se ha encontrado ninguna vista para id en Android FragmentActivity con ListFragment
- Android - ListView para cargar más elementos al llegar al final
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?