在ListView中选中并取消选中所有CheckBox

时间:2014-07-29 23:03:43

标签: android android-listview

我很惊讶我无法在Stack上找到可用于此的现有答案,所以我在这里。

我有一个ListFragment,其列表附加到SimpleCursorAdapter,该列表由以下row.xml文件定义的行组成:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   android:padding="6dip" >

   <CheckBox
       android:id="@+id/story_check_box"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:focusable="false"
       android:focusableInTouchMode="false" />

   <TextView
       android:id="@+id/story"
       android:layout_width="wrap_content"
       android:layout_height="24sp"
       android:lines="1"
       android:scrollHorizontally="true"
       android:singleLine="true"
       android:layout_alignBaseline="@+id/story_check_box"
       android:layout_alignBottom="@+id/story_check_box"
       android:layout_toRightOf="@+id/story_check_box" />

</RelativeLayout>

我使用适配器将列表连接到ListFragment中的以下代码:

adapter = new SimpleCursorAdapter(getActivity(), R.layout.row, null, new String[] { CProvider.Stories.TITLE }, new int[] { R.id.story }, 0);
setListAdapter(adapter);

然后我尝试在我的片段中使用CheckBox来切换所有列表复选框,如下所示:

CheckBox selectAll = (CheckBox) rootView.findViewById(R.id.select_check_box);
    selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            final ListView listView = getListView();
            for(int i=0; i < getListAdapter().getCount(); i++){
                View view = getViewByPosition(i, listView);
                CheckBox cb = (CheckBox)view.findViewById(R.id.story_check_box);
                if (isChecked) {
                    cb.setChecked(true);
                }
                else {
                    cb.setChecked(false);
                }
            }
        }

    });

我从这里得到getViewByPositionGet ListView children that are not in view几乎有效,但有些复选框无法检查(并且有一个模式对它,但我似乎无法弄清楚)。它似乎比我认为必要的有点笨拙。

我想要左边的复选框,所以我不想使用checktextviews。也许我需要扩展CursorAdapter并覆盖getView?

提前致谢。

2 个答案:

答案 0 :(得分:1)

也许我没有正确理解您的问题,但我理解的是您想检查并取消选中所有复选框,这要归功于一个&#34;全选复选框&#34;。

然后,我要做的是将&#34;选择所有复选框&#34;的状态。作为类的变量(作为布尔值),它被selectAll.setOnCheckedChangeListener覆盖并对适配器说'嘿嘿,我的状态改变了!&#34;每次复选框改变其状态。 像这样:

class Dummy{
    boolean isAllSelected = false;
    Checkbox selectAll = (find or create your CheckBox)
    selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) isAllSelected = true;
            else isAllSelected = false;
            listView.getAdapter().notifyDataSetChanged();
        }
    }

然后,你只需要覆盖这个适配器的getView()(就像你建议的那样)添加一个&#34; if(isAllSlected)&#34;条件。

对我而言,这听起来最容易做到,但每次用户点击复选框时调用notifyDataSetChanged()方法可能不太好(对于如此微小的更改而言,效率并不高)。无论如何,希望它有所帮助(我写的代码可能没有正确的语法:我直接在网站表单上写了它!)

答案 1 :(得分:0)

以下是我最近做的事情。除了照顾&#34;选择全部/取消全部&#34;功能,它在选择/取消选择列表项的文本时处理选中/取消选中复选框,反之亦然。我担心频繁调用getView,但setItemChecked会导致无论如何调用getView,因此可以避免多少调用getView的限制。正如评论中提到的ataulm,也许复合视图可以解决一个问题。

onCreateView

selectAllCheckBox = (CheckBox) rootView.findViewById(R.id.select_all_check_box);
    selectAllCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            final ListView listView = getListView();
            for(int i=0; i < getListAdapter().getCount(); i++){
                listView.setItemChecked(i, isChecked);
            }
        }
    });

我还使用以下代码创建了一个自定义SimpleCursorAdapter,它也使用了一个简单的ViewHolder类。在getView中,我检查列表中的哪些项目已被选中,并选中与这些项目对应的复选框。如果已经单击了相应的复选框(即,选中或取消选中),则还会将列表项设置为已选择的代码。

class AvailableCursorAdapter extends SimpleCursorAdapter {
    AvailableCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
        super(context, layout, c, from, to, flags);
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View row = super.getView(position, convertView, parent);
        ViewHolder holder = (ViewHolder)row.getTag();       
        if (holder == null) {                         
            holder = new ViewHolder(row);
            row.setTag(holder);
        }
        holder.storyCheckBox.setChecked(false);
        holder.story.setTextColor(Color.LTGRAY);
        long [] checkedIds = getListView().getCheckedItemIds();
        if (checkedIds != null) {
            for (int i = 0; i < checkedIds.length; i++) {
                if (checkedIds[i] == getListAdapter().getItemId(position)) {
                    holder.storyCheckBox.setChecked(true);
                    holder.story.setTextColor(Color.WHITE);
                    break;
                }
            }
        }
        final boolean isChecked = holder.storyCheckBox.isChecked();
        holder.storyCheckBox.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                getListView().setItemChecked(position, !isChecked);
            }
        });
        return(row);
    }
}

class ViewHolder {
    CheckBox storyCheckBox;
    TextView story = null;

    ViewHolder(final View row) {
        storyCheckBox = (CheckBox) row.findViewById(R.id.story_check_box);
        story = (TextView) row.findViewById(R.id.story);
    }
}

最后,以下代码会在单击一个ListItem时调用getView,以便根据需要选中或取消选中相应的复选框:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    ViewHolder holder = (ViewHolder) v.getTag();
    holder.storyCheckBox.setChecked(false);
    holder.story.setTextColor(Color.LTGRAY);
    long [] checkedIds = l.getCheckedItemIds();
    if (checkedIds != null) {
        for (int i = 0; i < checkedIds.length; i++) {
            if (checkedIds[i] == getListAdapter().getItemId(position)) {
                holder.storyCheckBox.setChecked(true);
                holder.story.setTextColor(Color.WHITE);
                break;
            }
        }
    }
}
相关问题