近期在用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两种解决方式及原因分析的更多相关文章

  1. django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方式

    现象 表单界面例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29sbG9yNTI1/font/5a6L5L2T/fontsize/400/fi ...

  2. Android ListView异步载入图片乱序问题,原因分析及解决方式

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...

  3. WEB安全实战(五)XSS 攻击的第二种解决方式(推荐)

    序 说到 XSS 攻击,前边已经有两篇文章在讲这个事了,这次又拿出来说,主要是针对近期工作中的一些新的问题.那么之前是怎么解决问题的呢?为什么又要换解决方式?以下就具体的跟大家分享一下. 旧方案 公司 ...

  4. 第一章 Mybtais的两种启动方式

    Mybatis的两种启动方式如下: 1.xml实现: xml的实现方式中,主要是通过手动创建SqlSession,然后调用session.selectOne()方法实现来实现. 首先是创建Config ...

  5. 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结

    史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...

  6. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

  7. String基础: String两种创建对象方式的比较

    字符串常量 在一般的语言中常量一旦声明则不可改变,在java中的字符串常量是以匿名对象来表示的 javaz中字符串两种定义方法: String strA= new String("hello ...

  8. JavaScript 函数的两种声明方式

    1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...

  9. 两种include方式及filter中的dispatcher解析

    两种include方式 我自己写了一个original.jsp,另外有一个includedPage.jsp,我想在original.jsp中把includedPage.jsp引进来有两种方式: 1.& ...

随机推荐

  1. Week11(11月21日)

    Part I:提问 =========================== 1.如何编辑更新一条记录? Part II:案例学习 =========================== MusicSt ...

  2. 基于visual Studio2013解决算法导论之023队列实现(基于数组)

     题目 基于数组的队列 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> #i ...

  3. iOS 打印日志的保存 (一)

    当我们真机调试app的时候,作为开发人员的我们可以很方便的通过Xcode的debug area查看相关的打印信息.而测试人员在对app进行测试的时候,一旦出现了crash,这时我们就需要把相关的打印信 ...

  4. R语言RJava安装步骤

     1.安装JDK 2.在R下运行install.packages("rJava") 2.环境变量设置 CLASSPATH=xxx\R-xxx\library\rJava\jri ...

  5. Axis2(9):编写Axis2模块(Module)

    Axis2可以通过模块(Module)进行扩展.Axis2模块至少需要有两个类,这两个类分别实现了Module和Handler接口.开发和使用一个Axis2模块的步骤如下: 1. 编写实现Module ...

  6. ELK 之一:ElasticSearch 基础和集群搭建

    一:需求及基础: 场景: 1.开发人员不能登录线上服务器查看详细日志 2.各个系统都有日志,日志数据分散难以查找 3.日志数据量大,查询速度慢,或者数据不够实时 4.一个调用会涉及到多个系统,难以在这 ...

  7. 知识点3-6:HTML辅助方法

    顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用,在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用HT ...

  8. WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇]

    原文:WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇] 在[第2篇]中,我们深入剖析了单调(PerCall)模式下WCF对服务实例生命周期的控制,现在我们来 ...

  9. eclipse中使用maven插件的时候,运行run as maven build/clean的时候报错

    -Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable a ...

  10. Mysql事务,并发问题,锁机制-- 幻读、不可重复读(转)

    1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约 ...