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懒加载
FragmentPagerAdapter与FragmentStatePagerAdapter构造方法增加了一个参数的传递
-
BEHAVIOR_SET_USER_VISIBLE_HINT
通过回调setUserVisibleHint()方法,来判断fragment的状态的显示或隐藏
-
BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
通过此状态位的判断,在执行instantiateItem()方法时进行判断
通过参数的判断,来控制fragment的生命周期函数走到哪里不再继续往下执行
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
状态; -
-
当fragment单独使用add时
-
使用setMaxLifecycle(Lifecycle.State.CREATED),配合add使用
-
使用setMaxLifecycle(Lifecycle.State.STARTED),配合add使用
-
使用setMaxLifecycle(Lifecycle.State.RESUMED),配合add使用
-
单独使用setMaxLifecycle
-
对RESUMED状态的Fragment进行操作CREATED操作
-
对RESUMED状态的Fragment进行操作STARTED操作
-
对RESUMED状态的Fragment进行CREATED操作,再进行STARTED操作
setMaxLifecycle这个方法貌似也只在FragmentPagerAdapter和FragmentStatePagerAdapter的构造方法传入的参数有用到,查看其它的文章时好像并没有看到对这个方法的调用,所以关于每个状态的详细使用暂时就不去过多记录了
总结
在AndroidX包下使用的懒加载方案通过使用FragmentPagerAdapter与FragmentStatePagerAdapter构造方法的第二个参数控制。
在调用构造方法时传入下面的参数,在onResume()方法中去执行延迟加载的操作
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT -