ListView+CheckBox两种解决方式及原因分析
近期在用ListView+CheckBox搞一个item选中的项目,我将CheckBox的focus设置为false,另我大喜的是,CheckBox居然能够选中(窃喜中),这么简单就搞定了,由于数据量较小,也没有发现什么问题。
后来数据多了。 页面须要滑动了, 发现了一个奇怪的问题,前面明明选中了,而再次滑动回去的时候居然变成未选中状态!
这是我刚開始写的那段错误的代码:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(App.sContext, R.layout.our_sp_item, null);
holder = new ViewHolder();
holder.checked = (CheckBox) convertView.findViewById(R.id.cb_our_sp_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
} if(isBatchMode) {
holder.checked.setVisibility(View.VISIBLE);
holder.checked.setChecked(mTasks.get(position).isChecked());
}else {
holder.checked.setVisibility(View.GONE);
} final int pos = position;
holder.checked.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mTasks.get(pos).setChecked(isChecked);
}
}); return convertView;
}
原因分析
关于错误的原因,我们先来分析一下, 哦,对了,在分析之前。先来看看我的上一篇博客:从一次意外開始说java匿名内部类。 相信对你理解非常有帮助。
以下我们開始分析出现上述状况的原因, 怎么分析呢? 跟着操作和代码走。
当我们滑动到第一条数据不再显示開始显示以下的数据的时候。由于复用了convertView, 也就是当前item的和第一条item共用了第一条convertView,这时看代码15行。setChecked改动了CheckBox的状态,而此时此刻肯定会去回调OnCheckedChangeListener,可是我们并没有给checkBox设置新的OnCheckedChangeListener, 也就是说。此时还是运行的曾经的回调。可是我们在匿名类中使用了外部方法的变量,鉴于在博客:从一次意外開始说java匿名内部类 所说的,此时的pos參数还是第一条item的pos,我们第一条数据的check状态就这么被操蛋的改动了。
解决方式
我们提供两种解决方式。
第一种。我们不使用setOnCheckedChangeListener的方式去改动保存的状态,而是换用Click
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(App.sContext, R.layout.our_sp_item, null);
holder = new ViewHolder();
holder.checked = (CheckBox) convertView.findViewById(R.id.cb_our_sp_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
} if(isBatchMode) {
holder.checked.setVisibility(View.VISIBLE);
holder.checked.setChecked(mTasks.get(position).isChecked());
}else {
holder.checked.setVisibility(View.GONE);
} final int pos = position;
holder.checked.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTasks.get(pos).changeChecked();
}
}); return convertView;
}
这样的方式为什么能解决呢? 非常easy,setChecked后,我们并没有提供Listener去改动值。代码也就没有了偷偷去改动的机会了。
另外一种,上面分析原因也说了,基本的原因还是在setChecked之前我们并没有设置新的Listener,那好办。我们把setOnCheckedChangeListener放到setChecked之前不就攻克了嘛。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(App.sContext, R.layout.our_sp_item, null);
holder = new ViewHolder();
holder.checked = (CheckBox) convertView.findViewById(R.id.cb_our_sp_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
} final int pos = position;
holder.checked.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mTasks.get(pos).setChecked(isChecked);
}
}); if(isBatchMode) {
holder.checked.setVisibility(View.VISIBLE);
holder.checked.setChecked(mTasks.get(position).isChecked());
}else {
holder.checked.setVisibility(View.GONE);
} return convertView;
}
ok。这两种方式都能够解决问题,各位客官喜欢哪个自己去挑。原因呢,我们也解析了,假设你对从一次意外開始说java匿名内部类 能充分的理解。那肯定是恍然大悟的,假设你还是不太明确,建议你再去看看前面一篇博客。
ListView+CheckBox两种解决方式及原因分析的更多相关文章
- django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方式
现象 表单界面例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29sbG9yNTI1/font/5a6L5L2T/fontsize/400/fi ...
- Android ListView异步载入图片乱序问题,原因分析及解决方式
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...
- WEB安全实战(五)XSS 攻击的第二种解决方式(推荐)
序 说到 XSS 攻击,前边已经有两篇文章在讲这个事了,这次又拿出来说,主要是针对近期工作中的一些新的问题.那么之前是怎么解决问题的呢?为什么又要换解决方式?以下就具体的跟大家分享一下. 旧方案 公司 ...
- 第一章 Mybtais的两种启动方式
Mybatis的两种启动方式如下: 1.xml实现: xml的实现方式中,主要是通过手动创建SqlSession,然后调用session.selectOne()方法实现来实现. 首先是创建Config ...
- 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结
史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...
- Android中Fragment与Activity之间的交互(两种实现方式)
(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...
- String基础: String两种创建对象方式的比较
字符串常量 在一般的语言中常量一旦声明则不可改变,在java中的字符串常量是以匿名对象来表示的 javaz中字符串两种定义方法: String strA= new String("hello ...
- JavaScript 函数的两种声明方式
1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...
- 两种include方式及filter中的dispatcher解析
两种include方式 我自己写了一个original.jsp,另外有一个includedPage.jsp,我想在original.jsp中把includedPage.jsp引进来有两种方式: 1.& ...
随机推荐
- Webgrid参数格式
显示图片 grid.Column(null,"图片",format:p=>Html.Raw(string.Format("<img src='{0}'/> ...
- 1, sync_with_stdio(), tie()的应用
一.sync_with_stdio() 这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑在了一起. ...
- 使用DiskGenius对虚拟机磁盘进行压缩
使用虚拟机的用户是否感觉到您的虚拟磁盘文件越来越大,都快把宝贵的磁盘空间(宿主机物理硬盘)占满了呢? 有人会想到,我直接启动虚拟机,然后把里面没用的数据删除了,不就行了吗?实际测试发现,这样删除后,存 ...
- 修复ubuntu播放wmv等视频没有声音问题
1. Mplayer or SMplayer 1.1 原因: 很可能是你没有安装 w32codes 1.2 解决方法: (1)下载 w32codes 官方站点 all-20110131.tar.bz2 ...
- 软件顾问可视设计的得力助手——PowerMockup
你可能是一位从事信息化的软件顾问,你也可能是一位软件设计师,你须要通过图形直观的向客户表达你的设计意图. 你可能已经积累了非常多的Powerpoint图形元素,但每次都要从以往的文件里到处寻找,浪费您 ...
- c# 课堂总结7--函数
函数:数据类型-变量类型-运算符号表达式-语句(顺序,分支,循环)-数字 程序里的函数:能完成一个相对独立功能的代码块.数学里的函数:高度抽象.函数四要素:函数名,输入(参数),输出(返回值类型),加 ...
- IOS常用设计模式之委托模式
对于iOS开发,举例Cocoa框架下的几个设计模式为大家分析.当然,Cocoa框架下关于设计模式的内容远远不止这些,我们选择了常用的几种:单例模式.委托模式.观察者模式.MVC模式. 委托模式 委托模 ...
- Qt 无边框窗体改变大小 完美实现
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- TimeUnit
转http://blog.csdn.net/hudashi/article/details/6936604 public enum TimeUnitextends Enum<TimeUnit&g ...
- Perl概述
@home = ("couch", "chair", "table", "stove"); 数组 数组.一个数组是多个标 ...