ViewPager中预加载与懒加载
预加载
为了让用户在切换过程中不卡顿,安卓官方默认创建当前item时,会创建第二个item,确保用户滑动时第二个item已经被创建,保持viewpager的平滑移动的效果。所以实现了预加载。
- viewpager.setCurrentItem(int item)
设置当前显示第几个item - viewpager.setOffscreenPageLimit(int limit)
limit参数默认是1,即使设置为0的话,默认值也为1(非当前显示页面)
默认是预加载当前显示item的两侧的itemview
如果是共5个item,当前显示在第3个item,则会缓存2,4的item
如果移动到4item,则清除2item,缓存3,5item
懒加载
如果预加载多个页面的时,由于预加载的原因,多个页面同时会对网络进行请求,造成流量浪费,卡顿等问题,懒加载解决的问题就是让页面上一些信息进行延迟加载,不至于同时进行太多并发的请求等
所以引入懒加载概念
Fragment懒加载
- setUserVisibleHint(boolean isVisibleToUser) 方法进行懒加载的控制(老办法,存在弊端)
之前是通过回调这个方法对页面当前显示和不显示的状态监听。
但是这个方法会在生命周期初始化执行之前就调用,是最先执行的方法,导致第一次执行时获取的boolean是false,并不是用户已经离开页面,而是页面还未初始化。
当执行onCreate()方法后再回调setUserVisibleHint()返回的才是真实的状态值。
/**
* 判断是否是初始化Fragment
*/
private boolean hasInitFragment = false;
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
//fragment中执行了onCreate方法后,isVisibleToUser为true,代表页面也已经显示
if (isVisibleToUser) {
hasInitFragment = true;
Log.i(TAG,"界面显示");
} else {
if (hasStarted) {
hasInitFragment = false;
Log.i(TAG,"界面不显示");
}
}
}
- setUserVisibleHint()方法调用缺点
因为这个方法会在onAttach()生命周期之前最先调用,可能会造成一些控件未初始化就被调用的问题,应严格注意(比如网络请求等) - AndroidX下通过使用setMaxLifecycle(Fragment fragment, Lifecycle.State state)可以实现懒加载
下文介绍总结
Viewpager中加载fragment如何实现懒加载
FragmentPagerAdapter与FragmentStatePagerAdapter构造方法增加了一个参数的传递
- BEHAVIOR_SET_USER_VISIBLE_HINT
通过回调setUserVisibleHint()方法,来判断fragment的状态的显示或隐藏,实现懒加载 - BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
通过此状态位的判断,在执行instantiateItem()方法时进行判断
通过参数的判断,来控制fragment的生命周期函数走到哪里不再继续往下执行
内部通过调用setMaxLifeCycle()方法实现
new ViewPagerAdapter(getSupportFragmentManager(),
FragmentPagerAdapter.BEHAVIOR_SET_USER_VISIBLE_HINT);
new ViewPagerAdapter(getSupportFragmentManager(),
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
//根据mBehavior的状态位进行判断
if (mBehavior == BEHAVIOR_SET_USER_VISIBLE_HINT) {
fragment.setUserVisibleHint(false);
}
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
}
Fragment中setMaxLifecycle使用总结
- Lifecycle.State五种状态解释
-
INITIALIZING
初始状态 -
CREATED
已创建状态 -
ACTIVITY_CREATED
完全创建,但是没有started -
STARTED
创建并启动,可见不可操作 -
RESUMED
创建启动并可操作
把生命周期方法从
onCreate -> onCretateView ->
onStart -> onResume -> onPause ->
onStop -> onDestoryView -> onDestory
视为从小到大排序;
生命周期状态CREATED
->STARTED
->RESUMED
视为从小到大排序;
CREATED状态
CREATED
即已创建状态,狭义的理解是生命周期方法走到onCreate
,如果当前fragment状态已大于CREATED
,则会使fragment生命周期方法走到onDestoryView
,如果小于CREATED
,则走到onCreate
;所以CREATED
有两种情况;
STARTED状态
同理,STARTED
状态也有两种情况,如果当前fragment状态已大于STARTED
,则会使fragment生命周期方法走到onPause
,如果小于CREATED
,则走到onStart
;
RESUMED状态
RESUMED
表示的状态比较特殊,只代表onResume
状态,无论大到小还是小到大,最终都是停留到onResume
状态;
setMaxLifecycle这个方法貌似也只在FragmentPagerAdapter和FragmentStatePagerAdapter的构造方法传入的参数有用到,查看其它的文章时好像并没有看到对这个方法的调用,所以关于每个状态的详细使用暂时就不去过多记录了
总结
在AndroidX包下使用的懒加载方案通过使用FragmentPagerAdapter与FragmentStatePagerAdapter构造方法的第二个参数控制。
在调用构造方法时传入下面的参数,在onResume()方法中去执行延迟加载的操作
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT