近期在用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. 从java main方法说开去(转)

    刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程, ...

  2. 基于visual Studio2013解决算法导论之050强连通分支

     题目 强连通分支 解决代码及点评 // 强连通分支.cpp : 定义控制台应用程序的入口点. // #include<iostream> #define MAX 100 using ...

  3. python模块介绍- multi-mechanize 性能测试工具

    python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...

  4. IT该忍者神龟Instant client required

    pply OS : Windows, Mac, Linux Apply Navicat Product : Navicat for Oracle, Navicat Premium Apply Navi ...

  5. 开源的Android视频播放器

    之前尝试自己解码视频,然后播放显示,虽然音视频都可以播放,但是实现不了音视频的同步,所以使用第三方的视频库Vitamio来实现视频播放器功能,这样自己只需要实现播放解码的制作不不要关心底层解码和显示问 ...

  6. 03-IOSCore - XML及解析、Plist

    一.XML 可扩展标记语言 是什么?是一段有规范的字符串, 用在哪?用在任何地方 语法: * 结点Node <结点名 属性名="属性值"> 结点内容 </结点名& ...

  7. m2eclipse简单使用,创建Maven项目 ,运行mvn命令(转)

    前面介绍了如何安装m2eclipse,现在,我们使用m2ecilpse导入Hello World项目. 选择菜单项File,然后选择Import,我们会看到一个Import对话框,在该对话框中选择Ge ...

  8. 初探 插头DP

    因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...

  9. 幻世(OurDream)2D图形引擎使用教程9——处理操作输入(3)

    声明:本教程版权归Lizcst Software Lab所有,欢迎转载,但是转载必须保留本段声明文字,并注明文章来源:http://blog.csdn.net/kflizcst 谢谢合作! 现在我们该 ...

  10. SharePoint 2013的100个新功能之搜索(二)

    一:名称建议 人员搜索中新的“名称建议”功能,微软引入了一种简单.直观的方式来根据名称找到用户.输入一个或多个字符,查看全部以其开头的名称,在所有的用户描述数据库都可用,在人员索引中也因此一样可用.该 ...