一、引入
在项目中应该经常会用到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的懒加载。代码如下:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70/**
* 标志已经初始化完成。
*/
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, 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;
// 视图销毁
isPrepared = false;
super.onDestroyView();
}不可以使用缓存的情况
我在Fragment所依附的Activity中的Toolbar中加了一个menu按钮,打算在Fragment中处理这个按钮的事件,使用默认的预加载会有一个Bug,即点击当前menu,但是menu所做的处理并不是当前可见的Fragment的menu,而是预加载页面的,也就是说点击比较混乱,处理的事件也不是我们想要处理的,这种情况如果添加了上述的懒加载,如果使用缓存的话,这样滑动过去之后在划回来menu的事件并没有刷新,所以说仍然会混乱。
1 |
|
三、致谢&源码
我的例子:https://github.com/sdwfqin/MicroText
感谢CSDN貌似掉线的文章:http://blog.csdn.net/maosidiaoxian/article/details/38300627