问题产生:
最近做项目遇到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()), R.layout.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。
1 2 3 4 5 6 7 8 |
|
打印结果:
before: 广东
after: 浙江
数据是肯定变了,难道数据闪烁是正常的,那为什么不用databinding时,没有出现数据闪烁现象?有人说全局刷新时layout重置。。。
网上不是有好多demo吗?去看看别人怎么用的,看看别人的代码是否有问题,于是下了个demo GitHub - jredthree/AllRecyclerDemo, 安装,运行,refresh,卧槽,居然没有闪烁!!!马上追踪代码,activity->adapter->onCreateViewHolder->onBindViewHolder。。。嗯?多了一行? holder.binding.executePendingBindings();这是what?没遇到过。加上这一行后,问题居然解决了。。。
/** * 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();//加一行,问题解决 }