目录
一、ViewPager 缓存页面与预加载
缓存页面
预加载
预加载带来的问题
解决(性能优化)
二、ViewPager 懒加载机制
ViewPager源码
ViewPager 是怎么展示出来的
Populate
FragmentPagerAdapter
三、ViewPager 与 ViewPager2 的差异
一、ViewPager 缓存页面与预加载
先有缓存页面,然后再预加载。因此,缓存的目的就是为了预加载。
缓存页面
1) setOffScreenPageLimit(int a): 设置缓存页面个数,例如 a = 2 就缓存4个Fragment,a = 3 就缓存 6 个Fragment(左右各3个)
ViewPager.setOffScreenPageLimit(1)
注意:设置 a = 0 不起作用,因为内部会重新修改为 1,那么缓存 2 个 Fragment。
例如:
当 setOffScreenPageLimit == 1 时,T3为当前展示页面(Fragment),则左右两边的T2 / T3就为缓存页面(Fragment)。
极端情况,T1为当前展示页面,由于左边没有了,那么左边就不管,就只管右边的缓存
同理,当 setOffScreenPageLimit == 2 时,左右两边各缓存 2 个Fragment,极端情况下仍然只缓存某一边的 Fragment
预加载
Fragment切换的时候,会预先加载缓存的不可见的 Fragment
设置 setOffScreenPageLimit = 1,当我们从 T1 切换到 T2 时,会预加载 T3。setOffScreenPageLimit = 2,当我们从 T4 切换到 T3 时,会预加载 T2 和 T1。
预加载带来的问题
1、预加载越多就会越卡。
2、如果一个 Fragment 占 1M, n个就占 nM,累计后就会出现 OOM(Out Of Memory),可能就会出现页面未响应的情况。
3、如果预加载的 Fragment 有网络请求等耗时操作,不仅浪费流量,还会很卡顿。
解决(性能优化)
使用懒加载,来解决预加载带来的问题。
二、ViewPager 懒加载机制
懒加载是什么?防止预加载,用到才加载,可见才加载,不可见就不加载。
懒加载,其实也就是延迟加载,就是等到该页面的 UI 展示给用户时,再加载该页面的数据(从网络、数据库等),而不是依靠 ViewPager 预加载机制提前加载两三个,甚至更多页面的数据。
目的:这样可以提高所属 Activity 的初始化速度,也可以为用户节约流量。而这种懒加载的方式也已经/正在被诸多 APP 所采用。
ViewPager源码
ViewPager是高级UI(有Adapter的UI都是高级控件,比如RecyclerView)
任何控件都逃离不了的原则,自定义View的基础:
1、onMeasure(): 测量(高宽等信息)
2、onLayout(): 排版 == 显示在那个位置
3、onDraw(): 画出来
ViewPager 是怎么展示出来的
Vieqpager + Adapter --> 适配器模式,然后用Adapter来完成数据在界面上的展示。
Populate
pupulate()函数在onMeasure() 和 setOffScreenPageLimit() 里调用。
populate() 中重要适配器的原理。populate 调用到 Adapter 里面(源码是这样解释的),populate 的5个函数是直接与 PagerAdapter 关联绑定的。
例如:pupulate()函数里 ViewPager里 startUpdate() --> PagerAdapter 里 startUpdate() --> FragmentPagerAdapter 里 startUpdate() --> (如果自己定义了Adapter 继承 FFragmentPagerAdapter) 自定义Adapter 里的 startUpdate()
FragmentPagerAdapter
instantiateItem() 与 setPrimaryItem() 是结合起来使用的。当由 t1 切换到 T3 时,T4 不会预加载,T1 也不再加载,只加载 T3。这就是源码里面的懒加载实现。
总的执行流程: (populate关联)Adapter 完成数据适配 --> 再执行 Fragment 的生命周期。
三、ViewPager 与 ViewPager2 的差异
1、ViewPager2内部实现是RecyclerView,所以ViewPager2的性能更高。
2、ViewPager2可以实现竖向滑动,只需要一个参数就可以改变滑动方向;ViewPager只能横向滑动。
3、ViewPager2只有一个adapter,FragmentStateAdapter继承自RecyclerView.Adapter。
ViewPager有两个adapter,FragmentStatePagerAdapter和FragmentPagerAdapter,均是继承PagerAdapter。FragmentStatePagerAdapter和FragmentPagerAdapter两者的区别是FragmentStatePagerAdapter不可以缓存,FragmentPagerAdapter可以缓存。
4、ViewPager2模式实现了懒加载,默认不进行预加载。内部是通过Lifecycle 对 Fragment 的生命周期进行管理。ViewPager会进行预加载,懒加载需要我们自己去实现。
5、ViewPager2 页面改变的监听是 registerOnPageChangeCallback();ViewPager 页面改变的监听是 setOnPageChangeListener();
registerOnPageChangeCallb