前言

这两天在做一个新需求:在一个列表界面,有两种特殊布局,一种是包含倒计时的,一种是展示一个网格布局的图片六宫格,这个六宫格内部实现是使用RecyclerViewGridLayoutManager实现,因为前期实现这个界面使用的是ListView,并没有做好局部刷新,所以当倒计时刷新时,六宫格布局也跟着刷新了,但是刷新时发现图片一直在闪烁,明明已经对图片做了缓存,并且对ImageView做了判断,加载过得不应该再次加载才对,后来经测试发现,只有六宫格数据充满六个才会在这样,五个一下完全没问题,我勒个去,这把我给坑的,各种查找资料,搜索社区……

原因

为这事还加了一天班,后来终于找到元凶,怪自己知识储备不够:
RecycleView是为了替代ListViewGridView而设计的,同时还能实现瀑布流的效果,内部管理ViewHolder,无需我们自己手动创建ViewHolder保存,为我们自动做好缓存和ItemView的复用;

但是在使用时需要注意RecyclerView内部默认只缓存5个Item,如果调用notifyDataSetChanged()方法刷新列表的,刷新后的列表数据小于5的话,不会重调用onCreateViewHolder()方法,但是如果大于5的话会重新调用onCreateViewHolder创建ItemView,因为RecyclerView内部只缓存了5个ItemView,所以RecyclerView提供了好多局部刷新的方法,这也是结合上边的特性新加的一些方法;

解决

比较简单的方法就是修改RecyclerView的缓存数量,完美解决刷新重新创建的问题:

// 修改 RecyclerView 的缓存数量,防止每次刷新都重新创建 ItemView
RecyclerView.RecycledViewPool pool = recyclerView.getRecycledViewPool();
pool.setMaxRecycledViews(DiscountHolderCreator.ITEM_VIEW_TYPE, 9);
recyclerView.setRecycledViewPool(pool);

以上是列表完整刷新的情况,如果我们设置加载更多或者插入的时候就不需要这样做了,因为我们不能无限的增加缓存个数,所以建议使用notifyItemInserted()notifyItemRangeChanged()方法进行刷新