为何懒加载
在�很多 App 都会有 �ViewPage + Fragment 的基本组合,但是众所周知 view�Pager 的 预加载机制,即使设置函数
setOffscreenPageLimit(0)
也不能改变默认值为 1 的事实,这样最少也会加载 3 个fragment,无疑对 app 的性能有所影响。
何谓懒加载
所谓的懒加载,其实也就是延迟加载,就是等到该页面的UI展示给用户时,再加载该页面的数据(从网络、数据库等),而不是依靠ViewPager预加载机制提前加载两三个,甚至更多页面的数据.这样可以提高所属Activity的初始化速度,也可以为用户节省流量.而这种懒加载的方式也已经/正在被诸多APP所采用.
怎样懒加载
核心函数 :
Fragment$setUserVisibleHint(boolean isVisibleToUser)
、Fragment$getUserVisibleHint()
实现的功能
- 在 Fragment 不显示时,不进行页面加载。 此时则需要
setUserVisibleHint(boolean isVisibleToUser)
来进行获取是否可见标志。 - 在 Fragment 没有创建完成时,不进行页面加载。此时需要
boolean hasCreate
来标记 当前 Fragment 是否完成初始化,完成初始化则hasCreate
为true
。 - 根据当前 Fragment 是否需要初始化,添加标志位
boolean needInit
,在当页面对用户可见并且
当前页面还没有加载时,该标志位needInit
置位为true
, 当前页面在加载结束后标志位needInit
置位为false
。
具体代码 基类 LazyFragment
public boolean hasLoaded = false; //标识是否已经加载过
private boolean hasCreated = false; //标识onCreateView是否已调用
private boolean needInit = false; //标识是否需要在onCreateView中```
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("lazy_load", "LazyFragment onCreateView. ");
View rootView = inflater.inflate(R.layout.fragment_lazy, container, false);
progressBar = $(rootView, R.id.fragment_lazy_progress_bar);
content = $(rootView, R.id.fragment_lazy_content_wrapper);
if (needInit) {
initWrapper();
needInit = false;
}
hasCreated = true;
return rootView;
}
//首先执行,比onCreateView 早
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Log.i("lazy_load", "LazyFragment setUserVisibleHint " + isVisibleToUser);
Log.i("lazy_load", "LazyFragment setUserVisibleHint---- " + hasLoaded);
if (isVisibleToUser && !hasLoaded) { //如果当前Fragment向用户展示且没有加载过,进行下一步判断
if (hasCreated) { //如果onCreateView已经被创建,此时进行加载
initWrapper();
} else { //如果Fragment没有创建,那么设置标记,在onCreateView中加载
needInit = true;
}
}
}
/**
* 此函数开始数据加载的操作,且仅调用一次
*/
private void initWrapper() {
LayoutInflater.from(getContext()).inflate(setContentView(), content);
initialize();
fadeOutView(progressBar, mShortAnimationDuration);
fadeInView(content, mShortAnimationDuration);
hasLoaded = true;
Log.i("lazy_load", "LazyFragment initWrapper " + hasLoaded);
}
/**
* 供子类使用,子类fragment初始化操作,此函数内部真正开始进行页面的一些列操作
*/
abstract void initialize();
/**
* 子类fragment设置布局,返回fragment要设定的布局
*
* @return 子类fragment要显示的布局
*/
@LayoutRes
abstract int setContentView();
参考博客:
吴小龙同學 – Android ViewPager + Fragment 懒加载实现
ViewPager+Fragment组合的预加载和懒加载