ListView+CheckBox实现全选,全不选功能
2016-08-31 10:08
316 查看
ListView+CheckBox实现全选,全不选功能
项目中有一个需求,选择联系人进行发送消息,可以实现全选,或者全不选,或者取消某一个已选中的.当点击确定按钮时,获取到已勾选的联系人信息.这里先来一张效果图:点击确定按钮后,输出已勾选联系人信息.
这里先把几个关键地方提一下:
listView+checkBox时,listView的item焦点会失去点击效果原因:开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),由于这些控件是强焦点控件,此时这些控件会抢占Item的焦点,所以常常当点击item时变化的是子控件,item本身的点击没有响应。解决方法有很多种,如使用焦点比较弱的控件,或者自己去处理事件分发来解决焦点冲突。下面给大家介绍一种比较简单的方法。
解决方法:在listView 的item 布局的顶层布局中 添加属android:descendantFocusability=”blocksDescendants”,就可以很简单的解决了。
- 我们看一下android:descendantFocusability属性:API描述如下:
android:descendantFocusability
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
当点击Item时,CheckBox实现联动效果(上一步已经处理了Item的焦点)
只需要添加ListView的点击事件,在点击事件中实现CheckBox联动效果。伪代码:
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TestCheckAllAdapter.ViewHolder holder = (TestCheckAllAdapter.ViewHolder) view.getTag(); // 会自动触发CheckBox的checked事件 holder.checkBox.toggle(); }
修改CheckBox的样式
首先,我们定义一个状态选择器(两张图片,一张是normal状态,另一种是pressed状态):
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checkable="true" android:drawable="@drawable/checkbox_pressed" /> <item android:state_checked="true" android:drawable="@drawable/checkbox_pressed" /> <item android:state_pressed="true" android:drawable="@drawable/checkbox_pressed" /> <item android:drawable="@drawable/checkbox_normal" /> </selector>
然后在style布局中添加CheckBox样式:
<!--自定义CheckBox的样式--> <style name="CustomCheckboxTheme" parent="@android:style/Widget.CompoundButton.CheckBox"> <item name="android:button">@drawable/selector_checkbox</item> </style>
最后,在布局中引入自定义CheckBox样式:
<CheckBox android:id="@+id/cb_check" style="@style/CustomCheckboxTheme" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:focusable="false" />
全选,全不选实现
这里就不细说了,代码中注释很详细.Activity类:
/** * Created by ListenerGao on 2016/8/29. * <p/> * listView实现全选,全不选功能 */ public class TestCheckAll extends BaseActivity implements AdapterView.OnItemClickListener { private static final String TAG = "TestCheckAll"; @BindView(R.id.tv_check) TextView tvCheck; @BindView(R.id.lv_check) ListView lvCheck; @BindView(R.id.ib_arrow_left) ImageButton ibArrowLeft; @BindView(R.id.bt_confirm) Button btConfirm; private List<TestCheckBean> mData; private TestCheckAllAdapter mAdapter; @Override protected int getLayoutResId() { return R.layout.activity_test_checkall; } @Override protected void initView() { ButterKnife.bind(this); tvCheck.setVisibility(View.VISIBLE); tvCheck.setText("全选"); ibArrowLeft.setVisibility(View.VISIBLE); } @Override protected void initData() { //初始化数据 mData = new ArrayList<>(); for (int i = 0; i < 15; i++) { TestCheckBean testCheckBean = new TestCheckBean(i, "张三" + i); mData.add(testCheckBean); } mAdapter = new TestCheckAllAdapter(this, mData); lvCheck.setAdapter(mAdapter); lvCheck.setOnItemClickListener(this); } @OnClick({R.id.ib_arrow_left, R.id.tv_check, R.id.bt_confirm}) public void onClick(View view) { switch (view.getId()) { case R.id.ib_arrow_left: finish(); break; case R.id.tv_check: if (tvCheck.getText().equals("全选")) { mAdapter.initCheckBox(true); mAdapter.notifyDataSetChanged(); tvCheck.setText("全不选"); } else if (tvCheck.getText().equals("全不选")) { mAdapter.initCheckBox(false); mAdapter.notifyDataSetChanged(); tvCheck.setText("全选"); } break; case R.id.bt_confirm: //得到选中状态条目的数据Bean Map<Integer, Boolean> checkedMap = mAdapter.getCheckedMap(); List<TestCheckBean> allChecked = new ArrayList<>(); for (int i = 0; i < checkedMap.size(); i++) { if (checkedMap.get(i)) { TestCheckBean testCheckBean = mData.get(i); allChecked.add(testCheckBean); } } //遍历输出已勾选条目的数据Bean for (TestCheckBean bean : allChecked) { Log.d(TAG, bean.toString()); } break; } } /** * listView+checkBox时,listView的item焦点会失去点击。 * 需要在listView 的item 布局的顶层布局中 添加属性:android:descendantFocusability="blocksDescendants" * 当点击item时checkBox实现联动效果 */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TestCheckAllAdapter.ViewHolder holder = (TestCheckAllAdapter.ViewHolder) view.getTag(); // 会自动触发CheckBox的checked事件 holder.checkBox.toggle(); } }
Adapter类:
/** * Created by ListenerGao on 2016/8/29. */ public class TestCheckAllAdapter extends BaseAdapter { private Context mContext; private List<TestCheckBean> mData; //存储CheckBox状态的集合 private Map<Integer,Boolean> checkedMap; public TestCheckAllAdapter(Context context, List<TestCheckBean> data) { this.mContext = context; this.mData = data; checkedMap = new HashMap<>(); //默认CheckBox为未勾选状态 initCheckBox(false); } /** * 初始化Map集合 * @param isChecked CheckBox状态 */ public void initCheckBox(boolean isChecked) { for (int i = 0; i<mData.size();i++) { checkedMap.put(i,isChecked); } } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_test_checkall,null); holder = new ViewHolder(convertView); convertView.setTag(holder); }else { holder = (ViewHolder) convertView.getTag(); } holder.tvName.setText(mData.get(position).getName()); // 勾选框的点击事件 holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 当勾选框状态发生改变时,重新存入map集合 checkedMap.put(position,isChecked); } }); //设置勾选框的状态 holder.checkBox.setChecked(checkedMap.get(position)); return convertView; } /** * 得到勾选状态的集合 * @return */ public Map<Integer,Boolean> getCheckedMap() { return checkedMap; } public static class ViewHolder{ @BindView(R.id.tv_name) public TextView tvName; @BindView(R.id.cb_check) public CheckBox checkBox; public ViewHolder(View view) { ButterKnife.bind(this,view); } } }
源码地址:
https://github.com/ListenerGao/MyTest/blob/master/app/src/main/java/com/listenergao/mytest/activity/TestCheckAll.java
相关文章推荐
- ListView CheckBox 完美实现多选、新增、删除、全选功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- Android中ListView绑定CheckBox实现全选增加和删除功能(DEMO)
- Android ListView长按弹出CheckBox,实现全选,反选,批量删除功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- Android ListView条目全选功能,不用checkbox实现!
- android基于ListView和CheckBox实现多选和全选记录的功能
- Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能
- android 基于ListView和CheckBox实现多选和全选记录的功能(转)
- 基于ListView和CheckBox实现多选和全选记录的功能
- Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能
- Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- BaseAdapter完美实现ListView中checkbox全选,取消,多选功能
- 如何实现listView中checkbox的全选与反选功能
- 基于ListView和CheckBox实现多选和全选记录的功能
- Android ListView条目全选功能,不用checkbox实现!