需要的功能很简单,就是一个带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的一个坑,你可掉进去过?的更多相关文章

  1. 如何让多个android listview同时使用一个滚动条

    如何让多个android listview同时使用一个滚动条 重新设置ListView的高度 /** * 设置listview高度,注意listview子项必须为LinearLayout才能调用该方法 ...

  2. 记录关于Android多线程的一个坑

    最近在写项目的时候由于联网用得比较频繁,就简单地封装了一个工具类,省得每次联网得时候都要把联网配置写一遍,代码如下: public class okhttp_plus { public static ...

  3. ASP.Net MVC的ViewBag一个坑,不要跳进去

    如鹏的学习管理系统是使用ASP.net MVC 5开发的,今天一个新版本发布后网站出现一个Bug,学生在下拉列表中选中的项再加载显示的时候发现仍然没被选中.详细一点说吧:假如有这样一个Action: ...

  4. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  5. Android listview addHeaderView 和 addFooterView 详解

    addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加 ...

  6. Android ListView实现不同item的方法和原理分析

    ListView实现不同item的方法和原理分析 一问题抛出Listview是android里面的重要组件,用来显示一个竖向列表,这个没有什么问题:但是有个时候列表里面的item不是一样的,如下图,列 ...

  7. Android开发的那些坑和小技巧

    1.android:clipToPadding 意思是控件的绘制区域是否在padding里面.默认为true.如果你设置了此属性值为false,就能实现一个在布局上事半功陪的效果.先看一个效果图. 上 ...

  8. Android listview viewpager解决冲突 滑动

    Android listview viewpager滑动 跳动 冲突解决 ListView中嵌套ViewPage有或者滑动手势冲突解决   在listview 上使用 addHeaderView 在第 ...

  9. [置顶] android ListView包含Checkbox滑动时状态改变

    题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...

随机推荐

  1. PDO exec 执行时出错后如果修改数据会被还原?

    PDO exec 执行时出错后如果修改数据会被还原? 现象 FastAdmin 更新了 1127 版本,但是使用在线安装方式出现无法修改管理员密码的问题. 一直是默认的 admin 123456 密码 ...

  2. NLTK在自然语言处理

    nltk-data.zip 本文主要是总结最近学习的论文.书籍相关知识,主要是Natural Language Pracessing(自然语言处理,简称NLP)和Python挖掘维基百科Infobox ...

  3. NHibernate ConfORM Mapping

    前言 昨天写了一篇fluent nhibernate通过约定的代码映射方式,NH在3.0版本以后已经集成了conform的代码映射方式,一直没注意也没使用过,今天试试怎么样. 步骤 1.通过confo ...

  4. Hive 安装操作

    本篇为安装篇较简单: 前提:1: 安装了hadoop-1.0.4(1.0.3也可以)正常运行2:安装了hbase-0.94.3, 正常运行 接下来,安装Hive,基于已经安装好的hadoop,步骤如下 ...

  5. C# mysql 连接Apache Doris

    前提:  安装mysql odbc驱动程序,目前只不支持8.0的最新版本驱动,个人使用的是5.1.12的驱动(不支持5.2以上版本),下载地址为: x64: https://cdn.mysql.com ...

  6. 517. Super Washing Machines

    ▶ 超级洗碗机.给定一个有 n 元素的整数数组,我们把 “将指定位置上元素的值减 1,同时其左侧或者右侧相邻元素的值加 1” 称为一次操作,每个回合内,可以选定任意 1 至 n 个位置进行独立的操作, ...

  7. MYSQL, REDIS 等数据库的介绍

    MySQL: 数据库概述 MySql安装和基本管理 MySQl创建用户和授权 初始mysql语句 库的操作 表的操作 数据类型 数据类型(2) 完整性约束 外键的变种 三种关系 数据的增删改 单表查询 ...

  8. leetcode532

    public class Solution { public int FindPairs(int[] nums, int k) { var pair = new Dictionary<strin ...

  9. linux中用date命令获取昨天、明天或多天前后的日期

    转自:http://www.linuxde.net/2011/10/1033.html 在实际操作中,一些脚本中会调用明天,或者昨天,或更多天前的日期,本文将叙述讲述用date命令实现时间的显示.在L ...

  10. 26.OGNL与ValueStack(VS)-N语法top语法

    转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html N语法[0]:<s:property value="[0]& ...