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.& ...
随机推荐
- mvc导航配置
<?xml version="1.0" encoding="utf-8" ?><Configuration> <Navigatio ...
- css如何li中选中后加上class属性js控制
<ul> <li class=""pageson"><span>1</span></li> <li> ...
- 用ASP编写购物车代码
网上购物已成为生活的潮流,在网上购物之后,想要随时查看自己已买的东西,想要随时删除或改动某件商品数量,要怎么做呢?以下我就来写代码及释义.先来做用户登陆页面(login.asp): <html& ...
- Android上成功实现了蓝牙的一些Profile
前段时间做蓝牙方面的开发,Google的Android只实现了Handset/Handfree和A2DP/AVRCP等Profile,而其 它常用的Profile如HID/DUN/SPP/OPP/FT ...
- GitHub 使用教程图文详解
大纲: 一.前言 二.GitHub简介 三.注册GitHub账号 四.配置GitHub 五.使用GitHub 六.参与GitHub中其它开源项目 七.总结 注,GitHub官网:https://git ...
- [转]PostgreSQL事务处理机制
原文链接:http://blog.chinaunix.net/uid-20726500-id-4040024.html 事务的实现原理可以解读为DBMS采取何种技术确保事务的ACID特性.Postgr ...
- python-Day4-迭代器-yield异步处理--装饰器--斐波那契--递归--二分算法--二维数组旋转90度--正则表达式
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- 高级UIKit-04(NSUserDefaults、NSKeyedArchiver、对象归档方法)
[day05_1_UserDefault]:判断应用程序是否是第一次运行 NSUserDefaults:用来保存应用程序的配置信息如:程序运行次数,用户登陆信息等. // 使用系统提供的NSUserD ...
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...
- Jquery学习笔记:删除节点的操作
假设如下的html代码 <div id="mydiv" style="width:100px;height:100px;border:1px solid red&q ...