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語句到底是什么用?調與不調有什么區別? 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM