Выберите все элементы ListView (настраиваемая строка с флажком в нем)

Что у меня: У меня есть ListView с настраиваемыми строками, с CheckBox и двумя TextViews в каждой строке. У меня есть кнопка "Выбрать все".

Что я хочу: Я хочу, чтобы при нажатии кнопки все CheckBox в ListView получили флажок/непроверенный.

В чем проблема: В OnClick кнопки "Выбрать все". я делаю это:

public void OnClickSelectAllButton(View view)
{
    ListView l = getListView();
    int count = l.getCount();
    for(int i=0; i<count; ++i) 
    {
       ViewGroup row = (ViewGroup)l.getChildAt(i);
       CheckBox check = (CheckBox) row.findViewById(R.id.checkBoxID);
       check.setChecked(true); // true for select all and false for unselect all etc..
    }
}

Здесь l.getChildAt(i) дает мне только видимые элементы. И когда индекс выходит из видимых элементов, возникает проблема. Я хочу проверить все CheckBox в List, а не только на видимые.

Ответы

Ответ 1

Это произойдет, потому что адаптер ListView повторно использует представления. То, как вы пытаетесь сделать, неверно. Я не думаю, что вам когда-либо приходилось обращаться к строкам списка через дочерние элементы списка.

Введите переменную в свою активность, которая будет удерживать текущее состояние (boolean checkAll). Когда пользователь нажимает кнопку, он должен установить "checkAll" в true и вызвать notifyDataSetChanged() (для массива) или requery() (для cursoradapter) в вашем адаптере ListView. В методе адаптера getView() введите проверку этого флага, поэтому if (checkAll) {check the check box}

Ответ 3

Я думаю, вы должны запустить эту долгосрочную задачу из потока пользовательского интерфейса. Когда вы нажимаете кнопку в OnClickListener:

new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i < list.getAdapter().getCount(); i++) {
                                final int position = i;
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        list.setItemChecked(pos, true);  
                                    }
                                });
                            }
                        }
                    }).start();     

и в onCreate():

this.mHandler = new Handler();

Каждый элемент в представлении списка должен быть Checkable, например CheckableRelativeLayout, который реализует интерфейс Checkable.