您的位置:首页 > 其它

关于 对lazyload的原理进行的学习

2017-10-23 15:34 344 查看
一、引言

LazyLoad,见文知意,就是懒惰地加载。理念和单例模式中的懒汉模式有异曲同工之处。

在做一个APP的时候,一个ViewPager包含多个Fragment,如果在打开APP的时候每个fragment自动加载,不管是从本地还是网络,都会占用一定的资源。

那我们可以不可以让这个fragment在需要被显示的时候才去加载、初始化呢?

在Fragment中有一个方法——setUserVisibleHint就能实现这个设想。

二、setUserVisibleHint的使用

setUserVisibleHint方法用于告诉系统,这个Fragment的界面对用户当前是否是可见的。所以我们只需要继承Fragment并重写该方法,即可实现在fragment可见时才进行数据加载操作,即Fragment的懒加载。

代码解释:

1.代码开始先设定标志变量isInit代表视图是否已经初初始化,在视图初始化的时候设置为true

标志变量isLoad代表视图是否对用户可见,在视图可见时设为true

2.定义了一个判断是否可以加载数据的方法isCanLoadData() ,*可以加载数据的条件:

* 1.视图已经初始化,isInit==true

* 2.视图对用户可见,getUserVisibleHint()返回true

3.定义了一个lazyLoad的抽象方法,该方法在isCanLoadData()里面调用。起到当视图初始化并且对用户可见的时候去真正的加载数据的作用。

4.定义了一个stopLoad方法,用于在切换到其他页面时停止加载数据。

5.定义方法onDestroyView,视图销毁的时候将Fragment的状态是否初始化变为false。

isInit = false;

isLoad = false;

6.视图是否已经对用户可见,系统的方法setUserVisibleHint(),在其中调用 isCanLoadData方法,实现Fragment数据的缓加载.

代码:

public abstract class LazyLoadFragment extends Fragment {
/**
* 视图是否已经初初始化
*/
protected boolean isInit = false;
protected boolean isLoad = false;
protected final String TAG = "LazyLoadFragment";
private View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(setContentView(), container, false);
isInit = true;
/**初始化的时候去加载数据**/
isCanLoadData();
return view;
}

/**
* 视图是否已经对用户可见,系统的方法
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isCanLoadData();
}

/**
* 是否可以加载数据
* 可以加载数据的条件:
* 1.视图已经初始化
* 2.视图对用户可见
*/
private void isCanLoadData() {
if (!isInit) {
return;
}
if (getUserVisibleHint()) {
lazyLoad();
isLoad = true;
} else {
if (isLoad) {
stopLoad();
}
}
}

/**
* 视图销毁的时候讲Fragment是否初始化的状态变为false
*/
@Override
public void onDestroyView() {
super.onDestroyView();
isInit = false;
isLoad = false;
}

protected void showToast(String message) {
if (!TextUtils.isEmpty(message)) {
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
}
}

/**
* 设置Fragment要显示的布局
*
* @return 布局的layoutId
*/
protected abstract int setContentView();

/**
* 获取设置的布局
*
* @return
*/
protected View getContentView() {
return view;
}

/**
* 找出对应的控件
*
* @param id
* @param <T>
* @return
*/
protected <T extends View> T findViewById(int id) {
return (T) getContentView().findViewById(id);
}

/**
* 当视图初始化并且对用户可见的时候去真正的加载数据
*/
protected abstract void lazyLoad();

/**
* 当视图已经对用户不可见并且加载过数据,如果需要在切换到其他页面时停止加载数据,可以覆写此方法
*/
protected void stopLoad() {
}
}


三、注意

isCanLoadData方法也在onCreateView中进行了调用,是因为要进行初始化的工作,毕竟ViewPager是会默认显示第一页的。setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isInit 的值。

setUserVisibleHint 的执行顺序是

setUserVisibleHint(false) -> onAttach -> onCreate -> setUserVisibleHint(true) -> onCreateView -> onActivityCreated ->…. -> onDetach参考ITluochen同学的blog
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐