问题产生
使用 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);
网友评论