RecyclerView使用databinding出现数据闪烁问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
RecyclerView使⽤databinding出现数据闪烁问题
When something takes longer than expected, write it down.
问题产⽣:
最近做项⽬遇到RecyclerView使⽤databinding时,出现数据闪烁,⽼⼤说,这问题不解决就不要⽤databinding。
闪烁图效果如下,点击Refresh,数据闪了⼀次:
明明数据没变,但数据却刷了⼀遍。
代码如下:
class TestDBAdapter extends RecyclerView.Adapter<TestDBViewHolder> {
private List<TestData> list;
public TestDBAdapter(List<TestData> list) {
this.list = list;
}
@Override
public TestDBViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ItemTestDbRecyclerViewBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), yout.item_test_db_recycler_view, parent, false);
return new TestDBViewHolder(binding);
}
@Override
public void onBindViewHolder(TestDBViewHolder holder, int position) {
holder.binding.setData(list.get(position));
// holder.binding.executePendingBindings();
}
@Override
public int getItemCount() {
return list.size();
}
}
class TestDBViewHolder extends RecyclerView.ViewHolder {
public ItemTestDbRecyclerViewBinding binding;
public TestDBViewHolder(ItemTestDbRecyclerViewBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public TestDBViewHolder(View itemView) {
super(itemView);
}
}
}
问题追踪:
从图中可以看到item从浙江-->⼴东-->浙江,这个简单,因为recycler view会重⽤item,刷新时,第⼀个元素使⽤了第四个元素的ViewHolder。
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof TaskItemViewHolder) {
final TaskItemViewHolder taskItemViewHolder = (TaskItemViewHolder) holder;
LogUtils.d("before: "+taskItemViewHolder.getBinding().getData());//打印bind前holder中的数据
taskItemViewHolder.bindTo(mList.get(position), position);
LogUtils.d("after: "+mList.get(position)+" position:"+position);//打印当前item的数据
}
}
打印结果:
before: ⼴东
after: 浙江
数据是肯定变了,难道数据闪烁是正常的,那为什么不⽤databinding时,没有出现数据闪烁现象?有⼈说全局刷新时layout重置。
/**
* Evaluates the pending bindings, updating any Views that have expressions bound to
* modified variables. This <b>must</b> be run on the UI thread.
*/
bindData后⽴即刷新!
难道要⽴刻刷新?还没有搞清楚。
问题解决:
@Override
public void onBindViewHolder(TestDBViewHolder holder, int position) {
holder.binding.setData(list.get(position));
holder.binding.executePendingBindings();//加⼀⾏,问题解决
}
遗留问题:
1. RecyclerView notifyDataChanged时,明明item的数据变化了,但为什么没有闪烁呢?
2. executePendingBindings语句到底是什么⽤?调与不调有什么区别?。