Comment obtenir les éléments sélectionnés dans Multi Select List View

J’utilise un adaptateur de tableau et à ceci j’ajoute une liste de chaînes de chaînes, la liste est multi-sélection, Comment puis-je obtenir les valeurs des éléments de liste sur lesquels j’ai cliqué?

my_contacts_list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice,conts_list); my_contacts_list.setAdapter(adapter); 

J’essayais de faire ça,

 SparseBooleanArray positions = my_contacts_list.getCheckedItemPositions(); int size=positions.size(); int i=0; while(i <= size){ conts_list.get(positions.get(i)); i++; } 

Mais position.get (i) est une liste de tableaux, comment récupérer les éléments sélectionnés alors?

SparseBooleanArray.get renvoie un booléen, mais je pense que vous devez le vérifier pour chaque position dans votre liste, par exemple

 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 */ } 

Cette API est un gâchis. Voici ce qui fonctionne pour moi.

 SparseBooleanArray checked = tags.getCheckedItemPositions(); for (int i = 0; i < checked.size(); i++) { if(checked.valueAt(i)) { Tag tag = (Tag) tags.getItemAtPosition(checked.keyAt(i)); Log.i("xxxx", i + " " + tag); } } 

Je pense que le moyen le plus rapide d’obtenir les informations de ce SparseArray est de parcourir les clés (en fait, je suis presque certain que les solutions ci-dessus ne fonctionneront pas dans tous les cas). ListView entrera une paire (index, true) dans le SparseBooleanArray pour chaque index sélectionné.

Donc, le code pourrait ressembler à ceci:

 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); } 

Je pense que la réponse de Daren Robbins est incorrecte, voici ma réponse:

 ArrayList ids = extras.getSsortingngArrayList("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))); } 

Supposons que les identifiants sont une arrayliste de la même taille que la liste contenant les identifiants des éléments de la vue liste.

La chose est que vous devez itérer tous les éléments de vue de liste, mais pas vérifiésPositions.

Définir les variables:

  • listView (l’instance de votre ListView)
  • noms (la ArrayList vous êtes)
  • saveCheckedName (enregistrer tous les noms cochés dans cette Arraylist)

      SparseBooleanArray checkedPositions = listView.getCheckedItemPositions(); for (int i = 0; i < subjectListView.getCount(); i++) { if (checkedPositions.get(i) == true) { saveCheckedName.add(names.get(i)); } } 

Comme beaucoup d’autres choses, les ListView sélection multiple sont un véritable problème dans Android.

Au lieu de simplement demander les éléments sélectionnés sous forme de List d’ Object (cher Google, voici ce que nous attendons):

 List selected_items = my_list_view.getSelectedItems(); 

nous sums obligés d’utiliser cette API incroyablement ridicule:

 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) { // } } } 

L'horriblement nommé SparseBooleanArray est SparseBooleanArray en appelant le nom encore plus horriblement nommé getCheckedItemPositions() sur ListView . Mais au lieu de renvoyer les positions de chaque élément sélectionné / vérifié dans la liste, il retourne la position de chaque élément de la liste qui a TOUJOURS été touché, qu'il soit actuellement sélectionné ou non! Incroyable, mais vrai.

Pour déterminer si l'élément est ACTUELLEMENT ACTUELLEMENT vérifié, nous sums obligés de tester valueAt(i) pour vérifier la véracité tout en parcourant le tableau d'éléments «a été touché».

En plus de cette folie, si nous voulons calculer le nombre d'éléments sélectionnés, nous num_selected être obligés d'incrémenter notre propre compteur (par exemple, num_selected ).

Avec des API comme celle-ci, il n'est pas étonnant que les développeurs soient en colère!

Comment j’ai résolu le problème avec une deuxième ArrayList:

  1. Création d’une seconde instance ArrayList
  2. Mise à jour de cette instance ArrayList avec les éléments UNCHECKED
  3. l’a ajouté à mon listadapter

     public void removeSelectedItems(){ updatedList = new ArrayList(); //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(this, android.R.layout.simple_list_item_multiple_choice, updatedList); setListAdapter(adapter);} 

J’espère que ce sera utile 🙂

 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 couple de choses à comprendre

  • C'est une liste de paires clé-valeur.
  • La clé est l'index d'une ligne, obtenez-le avec positions.keyAt (i)
  • La valeur est si la ligne à cet index est vérifiée ou non (true ou false), obtenez-la avec positions.valueAt (i)
  • positions.get (i) renvoie le même booléen que .valueAt (i)
  • Attention à ne pas confondre les index. Vous n'avez pas besoin ( et ne devriez pas ) parcourir votre liste entière. Utilisez int i pour parcourir les positions, mais n'utilisez pas i pour récupérer des objects de votre liste
  • Mais dans ce cas précis (listView.getCheckedPositions ()), il ne remplit que true (lignes vérifiées), vous n'avez donc pas besoin de vérifier en utilisant .get (i) ni avec .valueAt (i)

Exemple: Supposons que vous avez coché les 5ème et 8ème éléments de la liste (index 4 et 7), puis positions.size () == 2 et je serai 0 puis 1

Donc quand:

i == 0 alors keyAt (i) == 4

i == 1 alors keyAt (i) == 7

i == 0 OU i == 1 alors valueAt (i) == true ET get (i) == true

Pour info, voici comment Google l’a fait:

Extrait 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 arrayList = new ArrayList(); 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; } 

et voici ma version adaptée:

 public static List getAbsListViewCheckedItemPositions(AbsListView absListView) { SparseBooleanArray checked = absListView.getCheckedItemPositions(); List 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; } 

Nous l’utilisons dans notre classe utilitaire Android. Les génériques empêchent les avertissements du compilateur, mais vous pouvez les supprimer si votre adaptateur renvoie plusieurs types.

 public static  Collection getCheckedItems(ListView listView) { Collection 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; } 

Très simple, utilisez le code ci-dessous

 listViewRequests.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { AppCompatCheckedTextView checkBox = (AppCompatCheckedTextView) view; if (checkBox.isChecked() == true){ Log.i("CHECK",checkBox.isChecked()+""+checkBox.getText().toSsortingng()); } } }); 

Je pense qu’une autre option est de garder une trace de tout cela vous-même.

  list.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView listView, View selectedItem, int position, long itemId) { //Keep a reference here, and toggle a global variable.