什么是懒加载
当fragment完全可见的时候我们再去加载数据,我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,ViewPagerViewPager会默认在当前页面的左右两边至少预加载一个页面以保证ViewPager的流畅性,这就有可能会有一个问题,如果说我们的用户只原因一个界面,那么其他不可见的Fragment不也做了相关请求,既消耗了手机流量和服务器资源。所以我们的懒加载就出现了,所谓的懒加载,就是当Fragment可见时,才做相关数据加载的工作。
如何实现懒加载
- 方案1:
我们知道当一个当Fragment被预加载的时候,此Fragment的生命周期会从onAttach>onCreate->onViewCreate()->onCreateView->onActivityCreate()->onStart()->onResume(),所以我们很难从生命周期上来控制Fragment的懒加载。好在Fragment为我们提供了一个 setUserVisibleHint(boolean isVisibleToUser),这个方法其意义表示当前的Fragment是否对用户可见,我们就可以在这里通过添加标志位来处理懒加载:
/**
* Fragment的view
*
*/
protected View rootView;
/**
* 是否显示过
*/
private boolean isShow=false;
/**
* 是否已经加载过
*/
private boolean isLoaded=false;
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.d(TAG, "setUserVisibleHint: " + isVisibleToUser);
super.setUserVisibleHint(isVisibleToUser);
if (rootView != null) {
if (!isShow && isVisibleToUser) {
//当前从不可见变为可见
dispatchVisibleHint(true);
} else if (isShow && !isVisibleToUser) {
//当前从可见变为不可见
dispatchVisibleHint(false);
}
}
}
/**
* 从不可见到可见时,且正在显示,才去load数据,用isLoaded这个布尔值来控制只load一次
* 当从可见到不可见时,已加载过数据,可以做一些其他事情,比如停止播放音视频等
* @param isVisible
*/
private void dispatchVisibleHint(boolean isVisible) {
Log.d(TAG, "dispatchVisibleHint: " + isVisible);
isShow = isVisible;
if (isShow && !isLoaded) {
isLoaded = true;
loadData();
} else {
Log.d(TAG, "dispatchVisibleHint: do other things");
//do other things
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated: "+isShow+",getUserVisibleHint():"+getUserVisibleHint());
/**
* 在调用一次,保证布局初始化之后调用,也就是rootView不为空
*/
if (!isShow && getUserVisibleHint()) {
dispatchVisibleHint(true);
}
}
-
方案2:
上面用 setUserVisibleHint(boolean isVisibleToUser)这个方法,通过标志位的形式看起来并不优雅,Andrdoix给我们提供了一种更加方便的懒加载方式,当我们给ViewPager设置adapter时,用FragmentStateAdapter,并在其构造方法中传入BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT这个Beavior,这个参数可以控制Fragment的生命周期,控制当前显示的Fragment执行到onResume方法,其他不可见只是执行到onStart(),当前从可见到不可见又会执行到onPause(),这样我们就可以在onResume()中通过一个参数来控制他是否已经加载过了。
FragmentStatePagerAdapter fragmentStateAdapter = new FragmentStatePagerAdapter(getSupportFragmentManager(),
FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
private boolean isLoaded = false;
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart: ");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
if (!isLoaded) {
isLoaded = true;
loadData();
}
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause: ");
if (isLoaded) {
Log.d(TAG, "isLoaded: do other things");
}
}
- 方案3:
使用ViewPager2,再定义一个布尔值判断是否已经加载过就可以了。
总结
本文主要阐述了什么是Frament懒加载,以及懒加载的三种解决方案。
网友评论