• 抛砖引玉:关于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;
        }
    }
    

      

  • 相关阅读:
    从 OKR 工作法到 OKRs-E,落地OKR不能错过的转变
    OKR : 不要让目标仅仅成为口号
    [MySQL]Software caused connection abort: recv failed 问题分析与解决
    VS2010 vcpkgsrv.exe进程CPU占用高的解决方法
    Lync Server 2013企业版部署系列之九:前端部署后续工作
    Lync Server 2013企业版部署系列之八:安装lync server系统
    Lync Server 2013企业版部署系列之七:使用拓扑生成器规划拓扑
    Lync Server 2013企业版部署系列之六:AD准备
    Lync Server 2013企业版部署系列之五:前端服务器软件准备
    Lync Server 2013企业版部署系列之四:SQL准备
  • 原文地址:https://www.cnblogs.com/FightForFreedom/p/4656863.html
Copyright © 2020-2023  润新知