最近在项目中遇到了一个诡异的问题,在做一个填写报表界面,这个报表界面有N个item,每个item里面有N个EditText。如果我滑动到一定距离(item被回收复用)之后,再次滑过去的时候,item里面CheckBox的选中状态错乱,EditText的文本错乱。因为每个item里面全是EditText,没有其他的对比项,所以就以为是复用的问题,然后一直在找复用的问题,于是乎我设置了不可复用setIsRecyclable(false);
即:
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
setIsRecyclable(false);
}
但是,新的风暴又来了,这不仅会导致滑动不丝滑,错乱问题还是会存在,并且,添加和删除item的效果也没有了。于是乎,我果断删除了setIsRecyclable属性,另辟蹊径。
突然之间,脑中闪过一道闪电,想起了一个instance
的问题,于是就Boom了。在绑定ViewHolder的时候:
TextWatcher watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
list.get(position).setDes(s.toString());
}
};
viewHolder.etTarget.addTextChangedListener(watcher);
这是我的textWatcher,每次编辑后将新的值存到list里面去,这样在提交表单的时候,就可以直接提交。假如,我在这段代码前添加
if (viewHolder.etTarget.getTag() instanceof TextWatcher) {
viewHolder.etTarget.removeTextChangedListener(
(TextWatcher) viewHolder.etTarget.getTag());
}
viewHolder.etTarget.setText("" + list.get(position).getDes());
呵呵,问题解决。关键就在于,recyclerView他不会记住你的tag。如果加了tag,顺序不会错乱,滑动效果丝滑如初,添加和删除的效果也在。道理就有点像之前优化listView的时候,要给contentView加个tag,如果他有tag,则取他之前的tag的,如果没有再new一个。
CheckBox的选中状态跟这个原理差不多的,我就不贴出来了,老铁们自行撸码,加深印象,共勉。
哇咔咔,没想到这么快就有更新吧,虽然。。。
不过不重要,写在这里总有人会看到。
好了说正事,同样,今天也是遇到了一个RecyclerView里面的问题,同样是复用的问题,在Bind Item的时候。如果是选中的,则设置字体字号大一点,颜色深一点。于是:
if(list.get(position).isChecked){
itemHolder.textItem.setTextColor(activity.getResources().getColor(R.color.black));
itemHolder.textItem.setTextSize(17f);
}
我就这样愉快地把代码交上去了,但是新的风暴从来没有停息。在经过一顿滑动的骚操作之后,其他没有选中的item字号变大,颜色加深。这好尴尬啊,于是乎:
if(list.get(position).isChecked){
itemHolder.textItem.setTextColor(activity.getResources().getColor(R.color.black));
itemHolder.textItem.setTextSize(17f);
} else {
itemHolder.textItem.setTextColor(activity.getResources().getColor(R.color.black_70));
itemHolder.textItem.setTextSize(15f);
}
同理,是RecyclerView的复用问题。在遇到问题时,各位不要紧张,耐心排查排查,总会搞定。