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()), 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。

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重置。。。

网上不是有好多demo吗?去看看别人怎么用的,看看别人的代码是否有问题,于是下了个demo https://github.com/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();//加一行,问题解决
        }    

 

 

遗留问题:

1. RecyclerView notifyDataChanged时,明明item的数据变化了,但为什么没有闪烁呢?

2. executePendingBindings语句到底是什么用?调与不调有什么区别? 

 

 

posted on 2017-02-06 17:34  青崖绿舟  阅读(6506)  评论(2编辑  收藏  举报

导航