抛砖引玉:关于Android的ListView中CheckBox错乱

首先:参考了这篇翻译的文章:http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html

文章中关于说的Android中的Recycler比较模糊,Android会维持屏幕中显示的item+1个对象。但是复用的时候选择哪个对象来复用的机制并不明确,具体用的是什么数据结构,求告知。。。肯定不是简单的FIFO或LIFO。

关于checkBox,选中了之后,下滑之后返回就消失的问题。有以下两种方式供大家参考:

data是给TextView显示的。

isChecked是用来记录CheckBox是否选中的。

ArrayList<String> data;
ArrayList<Boolean> isChecked;
 class Holder {
        TextView name;
        CheckBox box;
    }

  

一:

用onClickedListener,使用这个监听器可以简单的避开CheckedBox选中消失的问题。

其中:holder.box.setTag(i);用来给监听器指明选择的索引。
 @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        if(view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.list_item, null);
            holder = new Holder();
            holder.box = (CheckBox) view.findViewById(R.id.cb_isChecked);
            holder.name = (TextView) view.findViewById(R.id.tv_name);
            view.setTag(holder);
        } else {
            holder = (Holder) view.getTag();
        }
        holder.name.setText(data.get(i));
        System.out.println("即将改变成" + isChecked.get(i) + "i" + i);
        holder.box.setChecked(isChecked.get(i));  
        holder.box.setTag(i);
        holder.box.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean hold = isChecked.get((Integer) view.getTag());
                isChecked.set((Integer) view.getTag(), !hold);
                System.out.println("compoundButton.getTag()" + view.getTag());
            }
        });
        return view;
    }

二.用onCheckedListener, 使用这个监听器,需要注意一些问题。

代码:和上面的一样,就是把onClickListener改成onCheckedlistener,结果就出现了选中消失的问题。

仔细看了在logcat中看了输出的结果,发现问题的所在:

当我们选中一个item时,假设此时item1被选中,下拉列表,到时item1隐藏,item10出现,并复用了item1的结构,由于在getView函数中item10被赋值是false,此时,onCheckedListener监听器响应了(如果使用onClickedListener就没有以下问题,因为它再此时不会响应),问题来了:

  因为在onCheckedListener根据view.getTag()来获得索引,而此时的索引是1,就是item1对象时setTag时留下的。

最终导致此时监听器把用来存储布尔值的线性表的索引1的位置赋值成了item10的值。

根据问题的成因,我们需要在 onCheckedListener响应前,让view.getTag()获得正确的索引,其实很简单只需要将

holder.box.setTag(i);放到holder.box.setChecked(isChecked.get(i));前面就可以了。

此解决方案的完整代码:

public class ListAdapter2 extends BaseAdapter {
    ArrayList<String> data;
    ArrayList<Boolean> isChecked;
    Context context;
    Holder holder;
    public ListAdapter2(Context context, ArrayList<String> data, ArrayList<Boolean> isChecked) {
        this.context = context;
        this.data = data;
        this.isChecked = isChecked;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int i) {
        return data.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        if(view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.list_item, null);
            holder = new Holder();
            holder.box = (CheckBox) view.findViewById(R.id.cb_isChecked);
            holder.name = (TextView) view.findViewById(R.id.tv_name);
            view.setTag(holder);

        } else {
            holder = (Holder) view.getTag();
        }

        holder.name.setText(data.get(i));
        System.out.println("即将改变成" + isChecked.get(i) + "i" + i);
        holder.box.setTag(i);

        holder.box.setChecked(isChecked.get(i));

        holder.box.setOnCheckedChangeListener(new CheckedListener());
        return view;
    }

    class CheckedListener implements CompoundButton.OnCheckedChangeListener {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            isChecked.set((Integer) compoundButton.getTag(), b);
            System.out.println("compoundButton.getTag()" + compoundButton.getTag() + "b" + b);
        }
    }

    class Holder {
        TextView name;
        CheckBox box;
    }
}

  

时间: 2024-10-07 18:38:42

抛砖引玉:关于Android的ListView中CheckBox错乱的相关文章

ListView中CheckBox错乱解决

思路: ListView在复用的时候会出现很多问题,CheckBox状态会出现错乱,解决思路: 1.使用Map集合的键值对的形式来存放position位置上CheckBox的状态 2.监听CheckBox的状态改变Listener,如果选中就往Map中添加一个position,true  如果取消,则将map中对应的键值对移除. 直接代码: private Map<Integer, Boolean> isCheckMap =  new HashMap<Integer, Boolean&g

android ListView中CheckBox错位的解决

貌似已经很晚了,但是还是想记下笔记,想让今天完满. 在ListView中加了checkBox,可是发现点击改变其选中状态的时候,发现其位置错乱.状态改变的并不是你选中的,百思不得其解.后面通过上网查资料,可是个说纷纭,但是我还是找到了解决办法. 在自定义的适配器中,对checkBox的设置如下: 记住两者的顺序,先对checkBox进行事件监听,再设置其状态.前提在布局中对checkBox的状态设为false. android ListView中CheckBox错位的解决,布布扣,bubuko.

android UI进阶之实现listview中checkbox的多选与记录

今天继续和大家分享涉及到listview的内容.在很多时候,我们会用到listview和checkbox配合来提供给用户一些选择操作.比如在一个清单页面,我们需要记录用户勾选了哪些条目.这个的实现并不太难,但是有很多朋友来问我如何实现,他们有遇到各种各样的问题,这里就一并写出来和大家一起分享. ListView的操作就一定会涉及到item和Adapter,我们还是先来实现这部分内容. 首先,写个item的xml布局,里面放置一个TextView和一个CheckBox.要注意的时候,这里我设置了C

案例:ListView中checkbox错位问题及onCreateContextMenu失效问题

本文涉及两个问题: ListView中checkbox错位问题 oncreateContextMenuListener失效问题 activity_listview_item.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layo

android的listview加checkbox实现单保存checkbox的勾选信息

最近做一个项目时想要增加安卓端的一个功能,就是增加一个activity上面有很多checkbox的勾选信息,然后可以给人选择多选框,看起来还算很简单..但是真正做起来就有很多麻烦了.. 虽然我对安卓有点了解,以前也看过一些代码,但都是看别人的代码,看代码当然简单啦,这下要全部自己写,这下有点棘手了,一开始真是无从下手啊,后来去网上查了一下,觉得有个人的写法不错,就是用listview导入adapter的布局这样子,于是我就照着他的代码的原型开始改了起来. 改了N久,终于改的有点样子了,其中也花了

实现listview中checkbox的多选与记录

android UI进阶之实现listview中checkbox的多选与记录 今天继续和大家分享涉及到listview的内容.在很多时候,我们会用到listview和checkbox配合来提供给用户一些选择操作.比如在一个清单页面,我们需要记录用户勾选了哪些条目.这个的实现并不太难,但是有很多朋友来问我如何实现,他们有遇到各种各样的问题,这里就一并写出来和大家一起分享. ListView的操作就一定会涉及到item和Adapter,我们还是先来实现这部分内容. 首先,写个item的xml布局,里

android 修改listview中adapter数据时抛出异常java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification问题

近日在做项目时遇到非必现crush,具体异常信息为: // Short Msg: java.lang.IllegalStateException // Long Msg: java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not mo

在android 自定义listView中绘制矩形

我想在android 在listview中绘制自定义的形状,我在网上找了代码但是没有运行通过,我现在有一个可以绘制矩形的 DrawView.java类,我想在我的自定义listView中展示这个对象. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 DrawView.java package com.example.h

如何在Android的ListView中构建CheckBox和RadioButton列表(Android版支持单选和多选的投票项目)

引言 我们在android的APP开发中有时候会碰到提供一个选项列表供用户选择的需求,如在投票类型的项目中,我们提供一些主题给用户选择,每个主题有若干选项,用户对这些主题的选项进行选择,然后提交. 本文以一个支持单选和多选投票项目为例,演示了在一个ListView中如何构建CheckBox列表和RadioButton列表,并分析了实现的原理和思路,提供有需要的朋友参考. 项目的演示效果如下. 数据源 通常我们的数据源来自于数据库.首先,我们构建投票项目类SubjectItem. /** * 主题