問題產生
使用 RecyclerView 調用 adapter.notifyDataSetChanged() 方法時,RecyclerView數據刷新閃爍。
RecyclerView刷新方法
//刷新所有
public final void notifyDataSetChanged();
//position數據發生了改變,那調用這個方法,就會回調對應position的onBindViewHolder()方法了
public final void notifyItemChanged(int position);
//刷新從positionStart開始itemCount數量的item了(這里的刷新指回調onBindViewHolder()方法)
public final void notifyItemRangeChanged(int positionStart, int itemCount);
//在第position位置被插入了一條數據的時候可以使用這個方法刷新,注意這個方法調用后會有插入的動畫,這個動畫可以使用默認的,也可以自己定義
public final void notifyItemInserted(int position);
//從fromPosition移動到toPosition為止的時候可以使用這個方法刷新
public final void notifyItemMoved(int fromPosition, int toPosition);
//批量添加
public final void notifyItemRangeInserted(int positionStart, int itemCount);
//第position個被刪除的時候刷新,同樣會有動畫
public final void notifyItemRemoved(int position);
//批量刪除
public final void notifyItemRangeRemoved(int positionStart, int itemCount);
問題原因分析
1、RecyclerView有一個RecyclerViewPool用來緩存已創建的item,不手動創建RecyclerViewPool時,系統會自動創建一個大小為5的RecyclerViewPool。
這就意味著RecyclerView的item個數大于5,每次刷新都會自動調用onCreateViewHolder()。
新創建的item不配置相關內容的話,將顯示布局文件中的默認值。從而導致有數據和無數據的閃爍。
2、閃爍主要由于RecyclerView使用的默認的動畫導致的,所以解決的方法就是修改默認的動畫。
問題解決方案
1、手動創建給RecyclerViewPool對象,指定它的大小,再傳給RecyclerView對象。
RecyclerView.RecycledViewPool pool= new RecyclerView.RecycledViewPool();
pool.setMaxRecycledViews(0, 10);
recyclerView.setRecycledViewPool(pool);
2、設置動畫執行時間為0來解決閃爍問題
// 通過設置動畫執行時間為0來解決閃爍問題
recyclerView.getItemAnimator().setChangeDuration(0);
3、屏蔽動畫方法
//只要設置為false,就可以不顯示動畫了,也就解決了閃爍問題
((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);