zoukankan      html  css  js  c++  java
  • 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语句到底是什么用?调与不调有什么区别? 

     

     

  • 相关阅读:
    前端代码规范
    使用CSS设置行间距,字间距.
    今天我们要说的画一个三角形,恩,画一个三角形,第一种呢是利用我们的html标签结合css来实现;而第二种方法就就是我们的html5新增的一个标签canves,这个canves就是网页画幕,那么顾名思义就是在网页里建造一个画板,用来画画,好,那接下来就和我一起去看看吧!
    javascript基础程序(算出一个数的平方值、算出一个数的阶乘、输出!- !- !- !- !- -! -! -! -! -! 、函数三个数中的最大数)
    css3 风车旋转
    css3简单的图片轮播
    css3 2D动画的基本用法和介绍
    Android 系统UI设计规则
    Android用户界面程序设计示例
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/xiangxing/p/6371202.html
Copyright © 2011-2022 走看看