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;
}