Fragment懒加载
一、引入
-
在项目中应该经常会用到ViewPager+Fragment来显示界面,但是ViewPager会有预加载,这样的话有些东西会无法把控,还有就是刚进入App时可能会一次请求多个接口,在显示上可能会造成某些不可预知的问题,虽然可以禁用掉预加载,但是目前据我所知用得较多的方式是修改ViewPager的源码,而且这个源码并不是最新版本,禁用后也不会缓存已加载过的页面,这样滑动时可能在用户体验上有些不友善。
-
Fragment有一个
setUserVisibleHint(boolean isVisibleToUser)方法,他可以监听当前页面是否在前台,但是他会在onCreateView方法之前执行,这样的话因为此时布局还没有加载,所以可能会引发NullPointException导致程序Crash,在这里记录下如何使用setUserVisibleHint进行懒加载并且避免程序Crash。
二、Fragment懒加载
-
首先介绍一下这个方法:
public void setUserVisibleHint(boolean isVisibleToUser),该方法用于告诉系统,这个Fragment的UI是否是可见的。所以我们只需要继承Fragment并重写该方法,即可实现在fragment可见时才进行数据加载操作,即Fragment的懒加载。 -
代码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768/*** 标志已经初始化完成。*/protected boolean isPrepared;/*** 当前界面是否可见*/protected boolean isVisible;/*** 当前是否加载过,避免重复加载(缓存,可选操作,有些情况加入反而会引发Bug)*/protected boolean isLoad = false;------/*** Fragment的UI是否是可见* <p>* 在onCreateView方法之前调用** @param isVisibleToUser*/public void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);if (isVisibleToUser) {// 当前页面可见isVisible = true;lazyLoad();} else {// 当前页面不可见isVisible = false;}}------public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {initInject();... ...// 界面加载完成isPrepared = true;lazyLoad();}------protected void lazyLoad() {// 状态判断,不符合不执行if (!isPrepared || !isVisible || isLoad) {return;}// 加载数据mPresenter.initData(url, pageId++);// 表示已经加载过isLoad = true;}------public void onDestroyView() {// 经过测试,当Fragment页面被销毁后如果继续在ViewPager滑过去重新显示了页面依然不加载// 状态还没变更过来,所以要在此处修改加载状态,表示本页没有加载过isLoad = false;super.onDestroyView();} -
不可以使用缓存的情况
我在Fragment所依附的Activity中的Toolbar中加了一个menu按钮,打算在Fragment中处理这个按钮的事件,使用默认的预加载会有一个Bug,即点击当前menu,但是menu所做的处理并不是当前可见的Fragment的menu,而是预加载页面的,也就是说点击比较混乱,处理的事件也不是我们想要处理的,这种情况如果添加了上述的懒加载,如果使用缓存的话,这样滑动过去之后在划回来menu的事件并没有刷新,所以说仍然会混乱。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
protected void lazyLoad() {
if (!isPrepared || !isVisible || isLoad) {
return;
}
initMenuClick();
// 不缓存
// isLoad = true;
}
/**
* 使用Activity中toolbar的menu
*/
private void initMenuClick() {
ShowImageActivity activity = (ShowImageActivity) getActivity();
Toolbar toolbar = activity.toolbar;
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_save:
saveImage();
break;
}
return true;
}
});
}
|
三、致谢&源码
我的例子:https://github.com/sdwfqin/MicroText
感谢CSDN貌似掉线的文章:http://blog.csdn.net/maosidiaoxian/article/details/38300627

浙公网安备 33010602011771号