Android ListView的一个坑,你可掉进去过?
需要的功能很简单,就是一个带checkbox的列表,提交时需要知道用户选择了那些项目,如下图:
使用SimpleAdapter作为数据适配器,重写SimpleAdapter.ViewBinder的方法,这样用比自定义Adapter要方便点,代码如下
datas定义是private List<Map<String, Object>> datas=null;
其中让Map中保存一项自我引用(my)绑定到checkBox
private Map<String, Object> populateMap(String lblNo,
Map<String, Object>... maps) { Map<String, Object> map = null;
if (maps.length > 0) {
map = maps[0];
} else {
map = new HashMap<String, Object>();
} map.put("lblNo", lblNo);
map.put("my", map);
map.put("checked", true);
return map;
}
private void bindAdapter(){
int[] to = new int[] { R.id.lblNo,R.id.ckbIt };
String[] from = new String[] { "lblNo","my"};
adapter = new SimpleAdapter(this, datas, R.layout.activity_post_list_item,
from, to);
// =======添加删除事件=======
SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {
private boolean supressEvent=false;
@Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
final Object d = data;
if (view instanceof CheckBox) {
final Map map=(Map)d;
CheckBox ckb = (CheckBox) view;
Log.d("T", "->Map"+map);
//ckb.setTag(map);
supressEvent=true; //需要避免在这里触发OnCheckedChange事件监听处理
ckb.setChecked((Boolean)map.get("checked"));
supressEvent=false;
ckb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d("T", "onCheckedChanged->Map"+map +" ischecked:" +isChecked);
if(supressEvent)return;
//Map map=(Map)buttonView.getTag();
map.put("checked", isChecked);
}
});
return true; //返回true表示不需要父类进行默认设置
//参考http://www.cnblogs.com/carmanloneliness/p/3500832.html
//http://www.cnblogs.com/carmanloneliness/p/3500832.html
}
return false;
}
};
adapter.setViewBinder(binder);
// =======End=======
lv.setAdapter(adapter);
}
刚开始时,没加上面红色注释那一句,发现运行时程序行为总不合要求。
后来发现是ckb在执行setChecked时会触发OnCheckedChange处理程序,
而SimpleAdapter采用的也是控件重用机制,就是当列表往上下拖时,那些被拖出屏幕外的控件会重用(绑定新的数据,参考代码里给的那链接),由于使用了final在执行ckb.setChecked((Boolean)map.get("checked")); 触发该控件的OnCheckedChange处理程序,而这个处理程序指向的数据项是前一次绑定的那行即前一次调用setViewValue传入的数据,这样就可能导致datas中的某个数据被意外修改,进而引起程序行为的不确定。
解决办法就是在执行ckb.SetChecked时做个标记,而事件处理程序根据这个标记排除拖动列表产生消息。
Android ListView的一个坑,你可掉进去过?的更多相关文章
- 如何让多个android listview同时使用一个滚动条
如何让多个android listview同时使用一个滚动条 重新设置ListView的高度 /** * 设置listview高度,注意listview子项必须为LinearLayout才能调用该方法 ...
- 记录关于Android多线程的一个坑
最近在写项目的时候由于联网用得比较频繁,就简单地封装了一个工具类,省得每次联网得时候都要把联网配置写一遍,代码如下: public class okhttp_plus { public static ...
- ASP.Net MVC的ViewBag一个坑,不要跳进去
如鹏的学习管理系统是使用ASP.net MVC 5开发的,今天一个新版本发布后网站出现一个Bug,学生在下拉列表中选中的项再加载显示的时候发现仍然没被选中.详细一点说吧:假如有这样一个Action: ...
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- Android listview addHeaderView 和 addFooterView 详解
addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加 ...
- Android ListView实现不同item的方法和原理分析
ListView实现不同item的方法和原理分析 一问题抛出Listview是android里面的重要组件,用来显示一个竖向列表,这个没有什么问题:但是有个时候列表里面的item不是一样的,如下图,列 ...
- Android开发的那些坑和小技巧
1.android:clipToPadding 意思是控件的绘制区域是否在padding里面.默认为true.如果你设置了此属性值为false,就能实现一个在布局上事半功陪的效果.先看一个效果图. 上 ...
- Android listview viewpager解决冲突 滑动
Android listview viewpager滑动 跳动 冲突解决 ListView中嵌套ViewPage有或者滑动手势冲突解决 在listview 上使用 addHeaderView 在第 ...
- [置顶]
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
随机推荐
- nodejs json-t 基本测试
安装npm包 npm i json-templater or yarn add json-templater 基本代码 var render = require('json-templater/str ...
- jQuery因mouseover,mouseout冒泡产生的闪烁问题
由于浏览器的冒泡行为.造成如果在一个DIV元素上同时定义了mouseover,mouseout的时候,当鼠标移动到DIV中的child子元素的时候,就会同时执行了两个操作mouseover和mouse ...
- 黄聪:[C#]如何获取变量的名字,不是值,是名称。返回名字的字符串
找了好久,最后在国外的论坛找到了解决办法,直接贴代码吧. 方法一: public static class MemberInfoGetting { public static string GetMe ...
- bzoj 3879: SvT
Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...
- Dynamics CRM 2011 权限管理
CRM系统基于角色的权限主要通过部门.角色.用户.团队来进行控制.每一个实体记录的所有者(Owner)必然是某一个用户或团队.一个用户或团队必然归属于一个且只归属于一个部门,但团队的成员即用户可以来自 ...
- Lifecycle of an ASP.NET Web API Message
ASP.NET Web API, as we know now, is a framework that helps build Services over HTTP. Web API was int ...
- Python算法应用实战之队列详解
队列是一种先进先出(First-In-First-Out,FIFO)的数据结构.队列被用在很多地方,比如提交操作系统执行的一系列进程.打印任务池等,一些仿真系统用队列来模拟银行或杂货店里排队的顾客.下 ...
- Cardboard Talk01 HeadTracker
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Android studio 3.0.0 | Cardboard 1.0 使用 Google 的 Cardboard开发V ...
- S 导客户主数据 及更新销售团队、组织、品牌
一.导入客户主表(INSERT) EXCEL模板 [Public] ConnectString=host="siebel://10.10.0.46:2321/HC_CRM/SMObjMgr_ ...
- ios的@property属性和@synthesize属性(转)
当你定义了一系列的变量时,需要写很多的getter和setter方法,而且它们的形式都是差不多的,,所以Xcode提供了@property 和@synthesize属性,@property用在 .h ...