RecyclerView相关

RecyclerView相关属性

禁用滑动事件 :  android:nestedScrollingEnabled="false"

设置滑动到边缘时无效果模式:  android:overScrollMode="never"


设置不显示滚动条:  android:scrollbars="none"

 四级缓存

1. mChangeScrap与 mAttachedScrap :用来缓存还在屏幕内的 ViewHolder
2. mCachedViews :用来缓存移除屏幕之外的 ViewHolder
3. mViewCacheExtension :开发给用户的自定义扩展缓存,需要用户自己管理 View的创建和缓存
4. RecycledViewPool :ViewHolder 缓存池

复用:从集合中去获取

入口:滑动 Move 事件 --> scrollByInternal --> scrollStep --> mLayout.scrollVerticallyBy --> scrollBy --> fill --> layoutChunk --> layoutState.next --> addView(view);

layoutState.next --> getViewForPosition --> tryGetViewHolderForPositionByDeadline -->

怎么从集合中去获取:tryGetViewHolderForPositionByDeadline,分几种情况去获取ViewHolder

  1. getChangedScrapViewForPosition -- mChangeScrap 与动画相关

  2. getScrapOrHiddenOrCachedHolderForPosition -- mAttachedScrap 、mCachedViews

  3. getScrapOrCachedViewForId -- mAttachedScrap 、mCachedViews (ViewType,itemid)

  4. mViewCacheExtension.getViewForPositionAndType -- 自定义缓存 -- (使用情况:局部刷新??)

  5. getRecycledViewPool().getRecycledView -- 从缓冲池里面获取

RecycledViewPool -- 缓存池

ViewHolder -- 包装View的 --- ItemView

当没有缓存的时候??--- mAdapter.createViewHolder --》 onCreateViewHolder

多级缓存的目的 -- 为了性能

创建ViewHolder 后 绑定: tryBindViewHolderByDeadline--》 mAdapter.bindViewHolder--》onBindViewHolder

回收(缓存)机制:看这一个情况--- ViewHolder

LinearLayoutManager.onLayoutChildren --> detachAndScrapAttachedViews --> scrapOrRecycleView

--> 1.recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存

  1. ViewHodler改变 不会进来 -- 先判断mCachedViews的大小
  2.  mCachedViews.size 大于默认大小 --- recycleCachedViewAt ​ --- >addViewHolderToRecycledViewPool --- 缓存池里面的数据都是从mCachedViews里面出来的
  3.  2.addViewHolderToRecycledViewPool --> getRecycledViewPool().putRecycledView(holder);
  4. scrap.resetInternal(); ViewHolder 清空

--> 2.recycler.scrapView(view);

缓存池 里面保存 只是 ViewHolder 类型 没有数据

public static class RecycledViewPool {

........

      @Nullable
        public ViewHolder getRecycledView(int viewType) {
            final ScrapData scrapData = mScrap.get(viewType);
            if (scrapData != null && !scrapData.mScrapHeap.isEmpty()) {
                final ArrayList<ViewHolder> scrapHeap = scrapData.mScrapHeap;
                for (int i = scrapHeap.size() - 1; i >= 0; i--) {
                    if (!scrapHeap.get(i).isAttachedToTransitionOverlay()) {
                        return scrapHeap.remove(i);
                    }
                }
            }
            return null;
        }


}

去查找缓存和复用的一种情况

入口:复用:RecyclerView.onLayout --> dispatchLayout --》 dispatchLayoutStep2 --》 onLayoutChildren --》 fill

缓存:fill -->recycleByLayoutState-->recycleViewsFromStart --> recycleChildren --> removeAndRecycleViewAt --> recycler.recycleView --> recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存

RecyclerView与ListView的对比

 RecyclerViewListView都是用于加载大量数据的控件,RecyclerView作为listview的改进加强型,相对ListViewRecyclerView做出了以下布局效果、局部刷新、动画效果、缓存知识优化:

1.布局效果

ListView 的布局比较单一,只有一个纵向效果;
RecyclerView 的布局效果丰富, 可以在 LayoutMananger 中设置:线性布局(纵向,横向),表格布局,瀑布流布局在RecyclerView 中,如果存在的 LayoutManager 不能满足需求,可以自定义
LayoutManager

2.item点击事件

RecyclerView 不支持 item 点击事件,只能用回调接口来设置点击事件
ListView item 点击事件直接是 setOnItemClickListener

3.局部刷新

ListView 中通常刷新数据是用 notifyDataSetChanged() ,但是这种刷新数据是全局刷新的(每个 item的数据都会重新加载一遍),这样一来就会非常消耗资源;
RecyclerView 中可以实现局部刷新,例如: notifyItemChanged()
如果要在 ListView 实现局部刷新,依然是可以实现的,当一个 item 数据刷新时在 Adapter中,实现一个notifyItemChanged() 方法,在方法里面通过这个 item position ,刷新这个 item 的数据

4.动画效果

RecyclerView 中,已经封装好 API 来实现自己的动画效果;并且如果我们需要实现自己的动画效果,我们可以通过相应的接口实现自定义的动画效果(RecyclerView.ItemAnimator 类),然后调用RecyclerView.setItemAnimator() (默认的有 SimpleItemAnimator DefaultItemAnimator );
但是ListView 并没有实现动画效果,但我们可以在 Adapter 自己实现 item 的动画效果;

5.缓存区别

层级不同
ListView 有两级缓存,在屏幕与非屏幕内。 mActiveViews + mScrapViews
RecyclerView ListView 多两级缓存:支持开发者自定义缓存处理逻辑, RecyclerViewPool( 缓存池 ) 。并且支持多个离屏ItemView 缓存(缓存屏幕外 2 itemView )。
mAttachedScrap +mCacheViews +mViewCacheExtension + mRecyclerPool
缓存内容不同
ListView 缓存 View
RecyclerView 缓存 RecyclerView.ViewHolder
RV优势
a.mCacheViews 的使用,可以做到屏幕外的列表项 ItemView 进入屏幕内时也无须 bindView 快速重用;
b.mRecyclerPool 可以供多个 RecyclerView 共同使用,在特定场景下,如 viewpaper+ 多个列表页下有优势.
总结缓存区别
1 ,封装了 viewholder Listview 需要自己写 ViewHolder 缓存,而 RecyclerView 已经帮我们实现了。
2 RecyclerView 的缓存机制有了加强, ListView 2 级缓存,而 RecyclerView 实现了 4 级缓存。
3 RecyclerView 相对于 ListView 最大的加强是实现了局部刷新,这对于 ListView 需要刷新全部列表进步很多,特别适用于那些数据源经常发生改变的情况。
 
ListView( 两级缓存 )

是否需要回createView是否需要回bindView生命周期备注
mActiveViewsonLayout函数周期内用于屏幕 itemView速重用
mScrapViewsmAdapter一致,当mAdatper更换时,mScrapViews即被清空
 
RecyclerView( 四级缓存 )
是否需要回createView是否需要回bindView生命周期备注

mAttachedScrap

onLayout函数周期内用于屏幕内itemview快速重用
mCacheViewsmAdapter一致,mAdapter被更换 时,mCacheViews即被缓存至 mRecyclerPool默认上限为2,即缓存屏幕外2 itemView
mViewCacheExtension不直接使用,需要用户在定制,默认不实现
mRecyclerPool与自身生命周期一致,不再被引用是即 被释放默认上限为5,技术上可以实 现所有RecyclerViewPool共用 同一个
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值