Как получить все отмеченные элементы из ListView? - PullRequest
41 голосов
/ 28 января 2011

У меня есть пара вопросов, которые мне не удалось выяснить.

Я пытаюсь получить все отмеченные элементы из ListView, но:

  1. Если я проверяю, а затем снимаю флажок с элемента, он возвращается как «проверенный» функцией getCheckedItemPositions()

  2. Я не знаю, как я могу выполнить это:

    SparseBooleanArray checked = list.getCheckedItemPositions();
    

Ответы [ 9 ]

75 голосов
/ 17 октября 2013

Другие ответы, использующие SparseBooleanArray, почти верны, но в них отсутствует одна важная вещь: SparseBooleanArray.size() иногда будет возвращать только количество true значений. Правильная реализация, которая перебирает все элементы списка:

SparseBooleanArray checked = list.getCheckedItemPositions();

for (int i = 0; i < list.getAdapter().getCount(); i++) {
    if (checked.get(i)) {
        // Do something
    }
}
11 голосов
/ 16 июля 2011

Я решил мой случай с этим:

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

Надеюсь, это кому-нибудь поможет.

8 голосов
/ 25 марта 2014

Ответ Джаретта великолепен, но это должно быть немного быстрее, поскольку он проверяет только те элементы в разреженном массиве, которые присутствуют в базовом массиве (только те, которые могут быть истинными):

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

6 голосов
/ 06 июня 2012

Вы можете выполнять итерацию по массиву SparseBooleanArray, используя цикл for и методы size () и get (index) объекта SparseBooleanArray.

РЕДАКТИРОВАНИЕ 3/2/2014: Люди отмечают, что метод size () SparseBooleanArray возвращает количество проверенных значений, а не истинную длину массива, поэтому я исправил свой ответ, чтобы учесть это. По сути, это то же самое, за исключением того, что вместо итерации по длине массива мы повторяем, пока не найдем все проверенные элементы. Так как нас интересует только количество проверенных элементов, не имеет значения, что при использовании этого метода мы можем фактически не добраться до конца массива (мы не увидим ничего после последнего проверенного элемента).

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
}
5 голосов
/ 05 января 2014

Мой мозг не любил циклически проходить через SparseBooleanArray, и мне не нужен был специальный адаптер, поэтому следующее было немного более интуитивным для меня:

  1. Не забудьте использовать CHOICE_MODE_MULTIPLE в onCreate ():

    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;
    } 
    
2 голосов
/ 22 мая 2012
 final long[] checkedIds = lv.getCheckItemIds();
            for (int i = 0; i < checkedIds.length; i++) {
                Log.d("checkedIds", "id checked: " + checkedIds[i]);
            }
1 голос
/ 03 апреля 2013

У меня была такая же проблема, и вот мое решение с 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));
}
1 голос
/ 18 января 2012

Только что увидел вопрос, и я столкнулся с той же проблемой.

Существует более простое решение, использующее 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;

}

Это решит обе проблемы проверенных пунктов.

0 голосов
/ 13 января 2016

В целом это решение, которое я использовал.

Где 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...