如何从多选列表视图中select项目
我正在使用一个数组适配器,并为此添加一个strings的数组列表,列表是多select,我怎样才能得到点击列表项的值?
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);
我正在努力做到这一点,
SparseBooleanArray positions = my_contacts_list.getCheckedItemPositions(); int size=positions.size(); int i=0; while(i <= size){ conts_list.get(positions.get(i)); i++; }
但是position.get(i)是一个数组列表,那么如何检索选中的项呢?
SparseBooleanArray.get返回一个布尔值,但我相信你需要检查它的列表中的每个位置,例如
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 */ }
这个API是一团糟。 这是对我有用的东西。
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); } }
我相信从这个SparseArray
获取信息的最快方法是遍历键(实际上我确信上述解决scheme在所有情况下都不起作用)。 ListView
将为每个选定的索引input一对(index,true)到SparseBooleanArray
。
所以代码可能是这样的:
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); }
我想达伦罗宾斯的答案是错的,这是我的答案:
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))); }
假设id是一个与列表视图大小相同的数组列表,包含列表视图中项目的ID
事情是你必须迭代所有的列表视图项目,但不checkedPositions。
定义variables:
- listView(ListView的实例)
- 名称(你是ArrayList)
-
saveCheckedName(保存所有选中的名字给这个Arraylist)
SparseBooleanArray checkedPositions = listView.getCheckedItemPositions(); for (int i = 0; i < subjectListView.getCount(); i++) { if (checkedPositions.get(i) == true) { saveCheckedName.add(names.get(i)); } }
像其他许多事情一样,多选列表ListView
在Android中是一个真正的问题。
而不是简单地将所选项目作为Object
List
(亲爱的Google,这是我们所期望的):
List selected_items = my_list_view.getSelectedItems();
我们被迫使用这个惊人的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) { // } } }
通过调用ListView
上更加可怕的命名的getCheckedItemPositions()
来填充可怕的SparseBooleanArray
。 但是不是返回列表中每个选中/检查项目的位置,而是返回列表中每个项目的位置,这个项目是否是当前实际选中的! 令人难以置信,但却是事实。
为了计算该项目是否被当前检查,我们被迫在循环“被触摸过的”项目数组的同时testingvalueAt(i)
的真实性。
除了这个疯狂之外,如果我们想要计算所选项目的数量,我们似乎被迫增加我们自己的计数器(例如num_selected
)。
有了这样的API,开发人员就不会感到愤怒了!
我如何解决与第二个ArrayList的问题:
- 创build了第二个ArrayList实例
- 用UNCHECKED项目更新了ArrayList实例
-
将其添加到我的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);}
希望这将是有益的:)
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 }
一些事情要了解
- 这是一个键值对列表。
- 关键是一行的索引,得到它的位置.keyAt(i)
- 值是在该索引行是否被检查(true或false),得到它与positions.valueAt(i)
- .get(i)返回与 .valueAt(i) 相同的布尔值
- 小心不要混淆索引。 你不需要(也不 应该 )遍历整个列表。 使用int我遍历位置,但不要使用我从列表中获取对象
- 但是在这个特定的情况下(listView.getCheckedPositions())它只填充true(checked行),所以你实际上不需要使用.get(i)和.valueAt(i)
例子:假设你已经检查了列表中的第5和第8项(索引4和7),然后位置。size()== 2,我将是0,然后是1
所以当:
我== 0然后keyAt(i)== 4
我== 1然后keyAt(i)== 7
我== 0或我== 1然后valueAt(i)==真和获得(i)==真
我们在我们的Android实用程序类中使用这个。 generics有助于防止编译器警告,但是如果适配器返回多个types,则可以将其删除。
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; }
我想另外一个select就是自己跟踪所有这些。
list.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> listView, View selectedItem, int position, long itemId) { //Keep a reference here, and toggle a global variable.
仅供参考,以下是Google如何做到的:
/** * 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; }
这是我的改编版本:
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; }
很简单,使用下面的代码
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().toString()); } } });