【问题标题】:How to get all checked items from a ListView?如何从 ListView 中获取所有选中的项目?
【发布时间】:2011-06-17 10:39:50
【问题描述】:

我有几个问题我没弄明白。

我正在尝试从ListView 中获取所有选中的元素,但是:

  1. 如果我选中然后取消选中某个元素,getCheckedItemPositions() 函数会将其返回为“已选中”

  2. 我不知道如何迭代:

    SparseBooleanArray checked = list.getCheckedItemPositions();
    

【问题讨论】:

标签: android listview checkbox


【解决方案1】:

使用SparseBooleanArray 的其他答案几乎是正确的,但它们缺少一件重要的事情:SparseBooleanArray.size() 有时只会返回true 值的计数。迭代列表中所有项目的正确实现是:

SparseBooleanArray checked = list.getCheckedItemPositions();

for (int i = 0; i < list.getAdapter().getCount(); i++) {
    if (checked.get(i)) {
        // Do something
    }
}

【讨论】:

  • 具有讽刺意味的是,这是唯一正确(和理智)的答案,而且没有一票。
  • 为什么需要遍历整个列表? getCheckedItemPositions() 方法不是为了避免这种情况而设计的吗?为什么不遍历 已经通过 getCheckedItemPositions() 方法为您选择的项? Foo objectAtCheckedRow = null; for (int i = 0; i &lt; positions.size(); i++) { /*positions.size() == 2*/ objectAtCheckedRow = adapter.getItem(positions.keyAt(i)); /*Do something significant with object here*/ }
  • @Sergey 如果你只需要选中的项,可以这样做,但你不能假设getCheckedItemPositions()返回的所有项都被选中。尝试选中一个项目,然后取消选中它; SparseBooleanArray 现在将包含该位置的条目,其值为 false
  • @Jarett 所以是的,我的代码是错误的,它不会产生与你相同的结果。我必须检查从 SparseBooleanArray 返回的每个项目:for (int i = 0; i &lt; positions.size(); i++) { if (positions.valueAt(i)) { Foo objectAtCheckedRow = adapter.getItem(positions.keyAt(i)); /*Do something significant with object here*/ } } 但我仍然认为没有必要遍历整个列表。
  • 其实我遇到了一个问题,只有这个答案是正确的。我有一个最多包含 10 个复选框的列表。如果检查了最后两项,则“getCheckedItemPositions()”将返回整个列表,但如果我询问大小,它将返回 2,因为只检查了 2 项,并且只遍历前两项,永远不会到达检查的。只有通过 Jarett 演示的从 ListAdapter 获取大小,我才能遍历整个列表。这应该被标记为正确答案。
【解决方案2】:

我用这个解决了我的问题:

public class MyAdapter extends BaseAdapter{
    public HashMap<String,String> checked = new HashMap<String,String>();
....
    public void setCheckedItem(int item) {


        if (checked.containsKey(String.valueOf(item))){
            checked.remove(String.valueOf(item));
        }

        else {
            checked.put(String.valueOf(item), String.valueOf(item));
        }
    }
        public HashMap<String, String> getCheckedItems(){
        return checked;
    }
}

要设置一个元素被选中:

public class FileBrowser extends Activity implements OnClickListener{        
private ListView list;

    ...
    list.setOnItemClickListener(new OnItemClickListener(){

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int item,
                long id) {

                        BrowserAdapter bla = (BrowserAdapter) parent.getAdapter();
                        bla.setCheckedItem(item);
                    }
    });

然后从类外获取选中的项目..

MyAdapter bAdapter;    
Iterator<String> it = bAdapter.getCheckedItems().values().iterator();
                    for (int i=0;i<bAdapter.getCheckedItems().size();i++){
                        //Do whatever
                        bAdapter.getItem(Integer.parseInt(it.next());
                    }

希望它可以帮助某人。

【讨论】:

  • 这正是我需要的。如果我想将选择限制为 1 项,我应该如何防止呢?
  • 我认为它不会起作用,除非你这样做。next() - 1 在 for 循环中迭代整个集合时。通过执行 it.next(),如果checkeditems 列表仅包含一项,它将抛出NoSuchElementException,如果它有超过一项,则跳过第一项。
【解决方案3】:

Jarett 的回答很好,但这应该会快一些,因为它只检查底层数组中存在的稀疏数组中的元素(只有那些可能是真的):

SparseBooleanArray checkedItemPositions = listView.getCheckedItemPositions();
    final int checkedItemCount = checkedItemPositions.size();
    for (int i = 0; i < checkedItemCount; i++) {
        int key = checkedItemPositions.keyAt(i);
        if (checkedItemPositions.get(key)) {
            doSomething(key);
        } else {
            // item was in the sparse array, but not checked.
        }
    }

专业提示:查看 SparseBooleanArray 的源代码,这是一个非常简单的类:

http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/util/SparseBooleanArray.java/?v=source

【讨论】:

    【解决方案4】:

    我的大脑不喜欢循环遍历 SparseBooleanArray,而且我不需要自定义适配器,因此以下内容对我来说更直观:

    1. 不要忘记在 onCreate() 中使用 CHOICE_MODE_MULTIPLE:

      getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

    2. 使用以下方法获取它们的ArrayList:

      // This example is to get an ArrayList of names (Strings)
      protected ArrayList<String> getNames() {
          ArrayList<String> names = new ArrayList<String>();
      
          for (int i = 0; i < getListView().getCount(); i++) {
              if (getListView().isItemChecked(i)) {
                  // Do whatever you need to in here to get data from
                  // the item at index i in the ListView
                  names.add(mUsers.get(i).getName());
              }
          }
      
          return names;
      } 
      

    【讨论】:

    • 这是完美的。没有理由让任何人陷入 SparseBooleanArray 的地狱。
    【解决方案5】:

    您可以使用 for 循环和 SparseBooleanArray 的 size() 和 get(index) 方法遍历 SparseBooleanArray。

    编辑 2014 年 3 月 2 日:人们指出 SparseBooleanArray 的 size() 方法返回检查值的数量,而不是数组的真实长度,所以我修改了我的答案来解释这一点。本质上它是相同的,只是我们不是迭代数组的长度,而是迭代直到找到所有检查的项目。由于我们只关心检查项的数量,因此使用此方法并不重要,我们实际上可能无法到达数组的末尾(我们不会看到最后一个检查项之后的任何内容)。

    SparseBooleanArray checked = list.getCheckedItemPositions();
    
    int numChecked = checked.size();
    
    for (int i = 0; numChecked > 0; i++){
        if (checked.get(i)){
            //the item at index i is checked, do something
            numChecked--; //We found a checked item, so decrement the number of checked items remaining
        }
        else
            //the item is not checked, do something else
    }
    

    【讨论】:

    • SparseBooleanArray.size() 将只返回真值的计数,而不是所有值。
    • SparseBooleanArray.size() ... "返回此 SparseBooleanArray 当前存储的键值映射的数量。"来自developer.android.com/reference/android/util/…。这不一定只是真正的价值。
    • 是的,但是从ListView.getCheckedItemPositions() 返回的SparseBooleanArray 的大小将仅等于检查项目的数量。未选中的项目不会显示在 SparseBooleanArray 中。
    【解决方案6】:
     final long[] checkedIds = lv.getCheckItemIds();
                for (int i = 0; i < checkedIds.length; i++) {
                    Log.d("checkedIds", "id checked: " + checkedIds[i]);
                }
    

    【讨论】:

    • 注意:此方法已弃用,您应该改用 getCheckedItemIds()(可从 API 8 / Android 2.2 获得)。
    【解决方案7】:

    刚看到这个问题,我也遇到了同样的问题。

    有一个更简单的解决方案,使用 SparseBooleanArray 来准确计算检查了多少项目。 这是我的 onClick 程序:

    @Override
    public void onClick(View v) {
    switch(v.getId()) {
      case R.id.button:
        SparseBooleanArray a = listView.getCheckedItemPositions();
        if(checked(vArray)>0) {
                String vCheckedList = "";
                for (int i = 0; i < nLength; i++) {
                    if (a.valueAt(i) && i < nLength-1 && a.size()>1)
                        vCheckedList += listView.getAdapter().getItem(vArray.keyAt(i))+"\n";
                    else if (a.valueAt(i))
                        vCheckedList += listView.getAdapter().getItem(vArray.keyAt(i));
                }
                Toast.makeText(getApplicationContext(), vCheckedList+ " is checked", Toast.LENGTH_SHORT).show(); 
                a.clear();
            } else
                Toast.makeText(getApplicationContext(), "No Item is Selected", Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
            }
    }
    

    检查方法:

    private int checked(SparseBooleanArray vArray) {
        int vCounter = 0;
        for(int i=0;i<vArray.size(); i++)
            if(vArray.valueAt(i))
                vCounter++;
        return vCounter;
    
    }
    

    这将解决检查项目的两个问题。

    【讨论】:

      【解决方案8】:

      我遇到了同样的问题,这是我使用SparseBooleanArray 的解决方案:

      SparseBooleanArray checkedPositions = lv.getCheckedItemPositions ();
      int size = checkedPositions.size ();
      for (int i=0 ; i<size ; i++) {
           // We get the key stored at the index 'i'
           int key = checkedPositions.keyAt (i);
           // We get the boolean value with the key
           Log.i (Tag, "checkedPositions(" + key + ")=" + checkedPositions.get (key));
      }
      

      【讨论】:

        【解决方案9】:

        总的来说,这是我使用的解决方案。

        其中 pos 是 Recyclerview 项目的位置

        SparseBooleanArray selected = new SparseBooleanArray();
        
        //OnClick listener here or whatever you use to check or uncheck an item
        if (selected.get(pos, false)) {
                selected.delete(pos);
            } else {
                selected.put(pos, true);
            }
        

        selected.size() 会显示有多少项目被选中

        selected.get(pos) 如果被选中,将返回 true

        如下所述,遍历所有被选中的项目:

        for (int i = 0; i < list.getAdapter().getCount(); i++) {
            if (selected.get(pos)) {
                // Do stuff
            }
        }
        

        【讨论】:

          【解决方案10】:

          这是我从 recyclerview 适配器获取检查项目的方式

          fun getAllCheckedItems(outList){
                   for (position in spareBooleanArray.keyIterator()) {
                      outList.add(mList.get(position)
                  }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多