最近在一个项目中,需要在ListView的item中加入CheckBox,但是遇到的一个问题是上下滑动的时候如果有选择了的CheckBox,就会出现选择项错误的问题,下面将个人的解决方法总结如下;
先说思路:
在ListView的Adapter中,用一个Map保存每一项item的选择状态,在getView方法中,设置Map中保存的某一项的选择状态就实现了状态的保存;
每一项的视图child.xml

    <CheckBox
android:id="@+id/item_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello" />

Adapter.java

public class CAdapter extends BaseAdapter {
private List<String> list;
private LayoutInflater inflater;
Map<Integer, Boolean> map;
private OnSelectedItemChanged listener;
private Holder holder = null; public CAdapter(Context context, List<String> list,
OnSelectedItemChanged listener) {
super();
inflater = LayoutInflater.from(context);
this.list = list;
map = new HashMap<Integer, Boolean>();
for (int i = 0; i < list.size(); i++) {
map.put(i, false);
}
this.listener = listener;
} @Override
public int getCount() {
return list.size();
} @Override
public Object getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
String item = list.get(position);
if (view == null) {
holder = new Holder();
view = inflater.inflate(R.layout.child, null);
TextView tv = (TextView) view.findViewById(R.id.item_tv);
CheckBox cb = (CheckBox) view.findViewById(R.id.item_cb);
holder.tv = tv;
holder.cb = cb;
view.setTag(holder);
} else {
holder = (Holder) view.getTag();
holder.tv.setText(item);
holder.cb.setChecked(map.get(position));
}
holder.tv.setText(list.get(position));
final CheckBox cb = holder.cb;
cb.setChecked(map.get(position));// 设置选择状态
cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
map.put(position, cb.isChecked());
listener.selectedItemChange(getSelectedCount(map));
}
});
return view;
} /**
* 获取选择的项的数目
*
* @param map
* @return
*/
public int getSelectedCount(Map<Integer, Boolean> map) {
int i = 0;
for (Entry<Integer, Boolean> entry : map.entrySet()) {
if (entry.getValue()) {
i++;
}
}
return i;
} class Holder {
TextView tv;
CheckBox cb;
} /**
* 向Activity暴露选择了多少项
*
* @author cj
*
*/
public interface OnSelectedItemChanged {
public void selectedItemChange(int count);
} public void selectAll() { // 全选
for (int i = 0; i < list.size(); i++) {
map.put(i, true);
}
notifyDataSetChanged();
} public void disSelectAll() { // 全不选
for (int i = 0; i < list.size(); i++) {
map.put(i, false);
}
notifyDataSetChanged();
} public void switchSelect() { // 反选
for (int i = 0; i < list.size(); i++) {
boolean select = map.get(i);
map.put(i, !select);
}
notifyDataSetChanged();
}
}

MainActivity.java

public class MainActivity extends Activity {
private ListView lv;
private CAdapter adapter; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
setAdapter(); } private void setAdapter() {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 50; i++) {
list.add("item - " + i);
}
adapter = new CAdapter(getApplicationContext(), list,
new OnSelectedItemChanged() {// Adapter接口暴露出来的选择项状态改变时选择的项的数目
@Override
public void selectedItemChange(int count) {
Log.e("SelectedCount - ", count + "");
}
});
lv.setAdapter(adapter);
} // 全选
public void selectAll(View v) {
adapter.selectAll();
} // 全不选
public void disSelectAll(View v) {
adapter.disSelectAll();
} // 反选
public void switchSelect(View v) {
adapter.switchSelect();
}
}

选择之后反选的效果(右边是点击反选之后的效果):

在上面用到一个比较好的思想就是用类的内部接口向外部调用类暴露本类的一些状态改变时,外部类可能想要获取的数据信息;
延伸思考:上面保存的状态是CheckBox,当需要使用RadioButton的时候,使用方法也是类似的;
但是RadioButton可能会有另一种需求{选择某一项的时候其它项就不选择,也即只选择一项},此种情况其实参考上面全选,反选的实现,实现起来也是比较简单,暂时没时间去写出来测试;

Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现的更多相关文章

  1. Android listview中使用checkbox

    最近比较忙碌,我也不知道忙的什么东西,打算写的博客写了一半,还没写完,今天先扯一扯项目中遇到的一个问题,一方面防止以后遇到这个问题忘记如何解决,另一方面希望可以提供给遇到同样问题的朋友一个思路.下面开 ...

  2. Android ListView 中的checkbox

    Q:ListView + CheckBox 当上下滚动的时候有事会自动选中或取消 A:这个与ListView的缓存机制有关.当你屏幕滚动后,ListView中的item选项视图先检查缓存中是否有视图, ...

  3. android listview中item通过viewpager实现《IT蓝豹》

    android listview中item通过viewpager实现 android listview中item通过viewpager实现,每一个item都支持viewpager实现图片切换功能.本项 ...

  4. js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false

    用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...

  5. 关于Winform下DataGridView中实现checkbox全选反选、同步列表项的处理

    近期接手一个winform 项目,虽然之前有.net 的经验,但是对一些控件的用法还不是很熟悉. 这段时间将会记录一些在工作中遇到的坎坷以及对应的解决办法,写出来与大家分享并希望大神提出更好解决方法来 ...

  6. jquery checkbox 复选框多次点击判断选中状态,以及全选/取消的代码示例

    2015年12月21日 10:52:51 星期一 目标, 点击当前的checbox, 判断点击后当前checkbox是否是选中状态. html: <input type="checkb ...

  7. Android开发 ---基本UI组件5:监听下拉选项,动态绑定下拉选项、全选/反选,取多选按钮的值,长按事件,长按删除,适配器的使用,提示查询数据,activity控制多按钮

    效果图: 效果描述: 1.当点击 1 按钮后,进入选择城市的页面,会监听到你选中的城市名称:动态为Spinner绑定数据 2.当点击 2 按钮后,进入自动查询数据页面,只要输入首字母,就会动态查找以该 ...

  8. 在GridView中实现全选反选的例子

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GridView控件.asp ...

  9. JQuery 全选 反选 获取Table 中指定td的元素值

    //全选 function initTableCheckbox() { var $thr = $('table thead tr'); var $checkAllTh = $('<th>& ...

随机推荐

  1. 说说CakePHP的关联模型之一 基本关联

    一个无论多么复杂的程序,拆开看无非是三种逻辑结构的组合:顺序结构.条件结构和循环结构. 类似的,数据库中表与表的之间的关联无外乎四种:一对一.一对多.多对一和多对多. CakePHP的模型层中定义了四 ...

  2. quartz 核心概念

    一.quartz 核心概念 1.scheduler是一个计划调度器容器,容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就 ...

  3. spark 相关

    Spark为什么会比mapreduce快? 1.Spark减少了中间过程的磁盘读写,数据很多时候不需要落地,从而提升了效率. 2.Spark基于内存的读写,减少了磁盘IO.node数据交互的通信时间. ...

  4. 227. Mock Hanoi Tower by Stacks【LintCode java】

    Description In the classic problem of Towers of Hanoi, you have 3 towers and N disks of different si ...

  5. 【转载】完全版线段树 by notonlysuccess大牛

    原文出处:http://www.notonlysuccess.com/ 今晚上比赛就考到了 排兵布阵啊,难受. [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时 ...

  6. Dev c++ 调试步骤

    不能调试的时候,修改下列地方: 1.在“工具”->编译选项->”Add following commands when calling complier”下面的编辑框里写入:-g3 2.在 ...

  7. 理解glance

    摘要: 本节介绍 OpenStack Image 服务 Glance 的基本概念. OpenStack 由 Glance 提供 Image 服务. 理解 Image 要理解 Image Service ...

  8. Python中的from等价于import的语法

    Python中导入module文件有两种方式:import和from.这里并不会列举import和from的具体使用方法,而是比较两者之间的差别. 对于from语句来说,它其实是等价于下面的impor ...

  9. 20145214 《Java程序设计》第2周学习总结

    20145214 <Java程序设计>第2周学习总结 教材学习内容总结 基本类型 整数:可分为short整数.int整数.long整数. 字节:即byte类型,可表示-128~127的整数 ...

  10. Thrift IDL使用方式

    I.背景 众所周知,Thrift是一个RPC的框架,其可用于不同语言之间的服务相互调用.比如最近接触到的一个运用环境: *前端使用Node.Js重构了部分我们的老旧代码(前后端未分离的SpringBo ...