1.RecyclerView 家族类图
2.RecyclerView 和 ListView的区别
1.从使用上
ListView:继承重写 BaseAdapter,自定义 ViewHolder 与 converView优化。
RecyclerView: 继承重写 RecyclerView.Adapter 与 RecyclerView.ViewHolder。设置 LayoutManager 来展示不同的布局样式
区别:
- ViewHolder的编写规范化,ListView是需要自己定义的,而RecyclerView是规范好的;
- RecyclerView复用item全部搞定,不需要像ListView那样setTag()与getTag();
- RecyclerView多了一些LayoutManager工作,但实现了布局效果多样化;
ListView只支持单一的纵向布局,RecyclerView支持线性布局,表格布局和瀑布流布局
ListView 支持设置 HeaderView 和 FooterView,而 RecyclerView 添加头部和底部需要自己在 Adapter中根据 ViewHolder 的 Type 编写。
2.数据刷新
ListView 刷新调用 notifyDataSetChanged() ,全局刷新数据 (每个 Item 数据会重新加载)
- 要在ListView实现局部刷新,依然是可以实现的,当一个item数据刷新时,可以在Adapter中,实现一个onItemChanged()方法,在方法里面获取到这个item的position(可以通过getFirstVisiblePosition()),然后调用getView()方法来刷新这个item的数据;
RecyclerView 支持局部刷新。
3.动画区别
在RecyclerView中,内置有许多动画API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果需要自定义动画效果,可以通过实现(RecyclerView.ItemAnimator类)完成自定义动画效果,然后调用RecyclerView.setItemAnimator();
但是ListView并没有实现动画效果,但我们可以在Adapter自己实现item的动画效果;
4.缓存区别
ListView和RecyclerView最大的区别在于数据源改变时的缓存的处理逻辑,ListView是”一锅端”,将所有的mActiveViews都移入了二级缓存mScrapViews,而RecyclerView则是更加灵活地对每个View修改标志位,区分是否重新bindView。
3.RecyclerView缓存
缓存原理说明
调用 notifyItemChanged( item_02) 时候,RecyclerView 认为 1, 3 , 4 , 5 未发生变化,此时会存入到 mAttachScrop 缓存集合中。而 item_02 是被修改了,存入到 mChangedScrap 集合中。
**总结:**mAttachScrop 保存的是原封不动的 ViewHolder。而 mChangedScrap 保存的是变化的 ViewHolder。
当将 Item_01 滑动出屏幕的时候,RecyclerView 认为该 ViewHolder 很可能会被再次滑进屏幕。此时将它存入到 mCachedViews 集合中。当反向滑动屏幕的时候,之前的 Item_01 又被滑进屏幕时,此时 Item_01 与原来的位置一致。也是不需要重新绑定数据的。
当 mCachedViews 中缓存的 ViewHolder 已满时,会将最先添加进的 ViewHolder 移到 mRecyclerPool 四级缓存集合中。
注意: mRecyclerPool 是不参与缓存阶段的,只参与复用阶段。
原理:
当每次调用: notifyItemChanged 或者 notifyDataChanged 都会调用:detachAndScrapAttachedViews() 方法。
该方法在向列表当中填充 Item 的时候,直接从 Recycler中去获取 ViewHolder。如果缓存池中获取不到 ViewHolder,则会去创建新的 ViewHolder,然后在重新绑定数据。