RecyclerView解决CheckBox复用问题

RecyclerView解决CheckBox复用问题 在onBindViewHolde中操作

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        final ViewHolder holde = (ViewHolder) holder;
        final Child item = list.get(position);

        onBind = true;
        //先判断仓库里有没有position对应的监听器
        if (getCBL(position) == null) {
            setCBL(position, new CBcheckedListener(position));
        }
        //要先起一个新的状态监听
        holde.selectItemCb.setOnCheckedChangeListener(new CBcheckedListener(position));
        //然后读取状态,顺序不能弄反,一旦反了就相当于setChecked用了上一次position的监听,把上一次保存的结果覆盖了
        holde.selectItemCb.setChecked(getState(position));
        onBind = false;

        String letter = (item.headpinyin.charAt(0) + "");
        //分类栏的显示和隐藏
        if (position > 0) {
            //获取上一个条目的首字母
            String previousLetter = (list.get(position - 1).headpinyin.charAt(0) + "");
            //如果当前letter和上一个的一样,那么则隐藏当前的字母View
            if (letter.equals(previousLetter)) {
                holde.letterTv.setVisibility(View.GONE);
            } else {
                holde.letterTv.setVisibility(View.VISIBLE);
                holde.letterTv.setText(letter);
            }
        } else {
            //说明是第0个,直接显示
            holde.letterTv.setVisibility(View.VISIBLE);
            holde.letterTv.setText(letter);
        }

        if (AppUtil.isNetworkAvailable(mActivity)) {
            if (item.getRosterPhoto() != null && item.getRosterPhoto().length() > 0) {
                holde.iconCircle.setVisibility(View.VISIBLE);
                holde.iconIv.setVisibility(View.GONE);
                Glide.with(mActivity).load(item.getRosterPhoto()).diskCacheStrategy(DiskCacheStrategy.ALL).dontAnimate().centerCrop().into(holde.iconCircle);
            } else {
                holde.iconCircle.setVisibility(View.GONE);
                holde.iconIv.setVisibility(View.VISIBLE);
                String name = item.getName();
                if (name != null) {
                    int length = name.length();
                    if (length > 2) {
                        holde.iconIv.setText(name.substring(length - 2, length));
                    } else {
                        holde.iconIv.setText(name);
                    }
                }
            }
        } else {
            holde.iconCircle.setVisibility(View.GONE);
            holde.iconIv.setVisibility(View.VISIBLE);
            String name = item.getName();
            if (name != null) {
                int length = name.length();
                if (length > 2) {
                    holde.iconIv.setText(name.substring(length - 2, length));
                } else {
                    holde.iconIv.setText(name);
                }
            }
        }

        holde.addressRv.setBackgroundColor(Color.WHITE);


        holde.friend_name.setVisibility(View.VISIBLE);
        holde.friend_name.setText(item.getName());
        holde.callIv.setVisibility(View.GONE);
        holde.mailIv.setVisibility(View.GONE);
        holde.messageTv.setVisibility(View.GONE);
        holde.nameTv.setVisibility(View.GONE);

    }

    //注意这里便是储存状态的仓库
    HashMap<Integer, Boolean> CBstate = new HashMap<>();

    //存储状态
    public void setState(int pos, Boolean state) {
        CBstate.put(pos, state);
    }

    //读取状态
    public Boolean getState(int pos) {
        Boolean s = CBstate.get(pos);
        return s == null ? false : s;
    }

    //保存监听器的仓库
    HashMap<Integer, CBcheckedListener> CBLStore = new HashMap<>();

    //存储
    public void setCBL(int pos, CBcheckedListener cbl) {
        CBLStore.put(pos, cbl);
    }

    public CBcheckedListener getCBL(int pos) {
        return CBLStore.get(pos);
    }

    //这里自定义一个勾选监听的实现类,方便传递position
    class CBcheckedListener implements CompoundButton.OnCheckedChangeListener {
        int pos = 0;

        public CBcheckedListener(int pos) {
            this.pos = pos;
        }

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            //当用户点选时触发此事件进行存储状态,下次再滚到这个position的item时会在执行上面的代码读出状态正确展示给用户
            if (!onBind) {
                setState(pos, isChecked);
                notifyDataSetChanged();
                select.clear();
                for (Map.Entry<Integer, Boolean> entries : CBstate.entrySet()) {
                    if (entries.getValue()) {
                        select.add(list.get(entries.getKey()));
                    }
                }
                if (select != null && select.size() == 0) {
                    selectPeopleTv.setText("已选择:");
                    selectFl.setEnabled(false);
                    selectDefineTv.setEnabled(false);
                } else if (select != null && select.size() > 0) {
                    selectPeopleTv.setText("已选择:" + select.size() + "人");
                    selectFl.setEnabled(true);
                    selectDefineTv.setEnabled(true);

                    selectFl.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (messageInfo != null) {
                                showPop();
                                for (int i = 0; i < select.size(); i++) {
                                    sendMessage(select.get(i), i, select.size() - 1);
                                }
                                finish();
                            }

                        }
                    });
                }

            }

        }
    }

条目点击选择CheckBox

class RootClickListener implements View.OnClickListener {
        int pos = 0;

        public RootClickListener(int pos) {
            this.pos = pos;
        }

        @Override
        public void onClick(View v) {
            //当用户点选时触发此事件进行存储状态,下次再滚到这个position的item时会在执行上面的代码读出状态正确展示给用户
            if (!onBind) {
                Boolean state = getState(pos);
                holde.selectItemCb.setChecked(!state);
                setState(pos, !state);
                notifyDataSetChanged();
                select.clear();
                for (Map.Entry<Integer, Boolean> entries : CBstate.entrySet()) {
                    if (entries.getValue()) {
                        select.add(list.get(entries.getKey()));
                    }
                }
                if (select != null && select.size() == 0) {
                    selectPeopleTv.setText("已选择:");
                    selectFl.setEnabled(false);
                    selectDefineTv.setEnabled(false);
                } else if (select != null && select.size() > 0) {
                    selectPeopleTv.setText("已选择:" + select.size() + "人");
                    selectFl.setEnabled(true);
                    selectDefineTv.setEnabled(true);

                    selectFl.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (messageInfo != null) {
                                showPop();
                                for (int i = 0; i < select.size(); i++) {
                                    sendMessage(select.get(i), i, select.size() - 1);
                                }
                                finish();
                            }

                        }
                    });
                }

            }
        }

    }

解决Android RecyclerView : notifyDataSetChanged() IllegalStateException

private boolean onBind;

public ViewHolder(View itemView) {
    super(itemView);
    mCheckBox = (CheckBox) itemView.findViewById(R.id.checkboxId);
    mCheckBox.setOnCheckChangeListener(this);
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if(!onBind) {
        // your process when checkBox changed
        // ...

        notifyDataSetChanged();
    }
}

...

@Override
public void onBindViewHolder(YourAdapter.ViewHolder viewHolder, int position) {
    // process other views 
    // ...

    onBind = true;
    viewHolder.mCheckBox.setChecked(trueOrFalse);
    onBind = false;
}
发布了63 篇原创文章 · 获赞 10 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/yin13753884368/article/details/73379079