上次写了一个问答项目,用的fragment+viewpager架构,后来发现,划了几次之后,再划回来,会重新加载布局,重新获取数据,这样整个程序和卡,并且占用太多的网络资源。
当时的解决办法是,自己重写view,用最基本的Basepageradapder,算是不是很优雅的解决了问题。
当时知道是重新调用onCreateView方法原因,但是没有好的解决办法,现在知道了,这里记载一下。
我实验了viewpager加载四个fragment:
第一次进入的时候:
1
2
3
4
5
6
|
<span style=
"font-size:18px;"
>
03
-
01
13
:
50
:
16.151
22667
-
22667
/com.graypn.modelproject I/onCreate1﹕ onCreate
03
-
01
13
:
50
:
16.151
22667
-
22667
/com.graypn.modelproject I/onCreateView1﹕ onCreateView
03
-
01
13
:
50
:
16.161
22667
-
22667
/com.graypn.modelproject I/onActivityCreated1﹕ onActivityCreated
03
-
01
13
:
50
:
16.161
22667
-
22667
/com.graypn.modelproject I/onCreate2﹕ onCreate
03
-
01
13
:
50
:
16.161
22667
-
22667
/com.graypn.modelproject I/onCreateView2﹕ onCreateView
03
-
01
13
:
50
:
16.161
22667
-
22667
/com.graypn.modelproject I/onActivityCreated2﹕ onActivityCreated</span>
|
往右滑动到第二个界面:
1
2
3
|
<span style=
"font-size:18px;"
>
03
-
01
13
:
51
:
22.391
22667
-
22667
/com.graypn.modelproject I/onCreate3﹕ onCreate
03
-
01
13
:
51
:
22.391
22667
-
22667
/com.graypn.modelproject I/onCreateView3﹕ onCreateView
03
-
01
13
:
51
:
22.401
22667
-
22667
/com.graypn.modelproject I/onActivityCreated3﹕ onActivityCreated</span>
|
往右滑动到第三个界面:
1
2
3
4
|
03
-
01
13
:
55
:
24.351
24165
-
24165
/com.graypn.modelproject I/onDestroyView1﹕ onDestroyView
03
-
01
13
:
55
:
24.351
24165
-
24165
/com.graypn.modelproject I/onCreate4﹕ onCreate
03
-
01
13
:
55
:
24.351
24165
-
24165
/com.graypn.modelproject I/onCreateView4﹕ onCreateView
03
-
01
13
:
55
:
24.361
24165
-
24165
/com.graypn.modelproject I/onActivityCreated4﹕ onActivityCreated
|
往右滑动到第四个界面:
1
|
03
-
01
13
:
56
:
22.021
24165
-
24165
/com.graypn.modelproject I/onDestroyView2﹕ onDestroyView
|
往左划到第三个界面:
1
2
|
03
-
01
13
:
58
:
09.541
24165
-
24165
/com.graypn.modelproject I/onCreateView2﹕ onCreateView
03
-
01
13
:
58
:
09.541
24165
-
24165
/com.graypn.modelproject I/onActivityCreated2﹕ onActivityCreated
|
结论:viewpager会加载和当前页面相连的两个fragment,会销毁相邻第三个页面的view,再次调用是会重新oncreateview和onactivityreate。
我们需要优化自己的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
|
<span style=
"font-size:18px;"
>
/**
* 提供了fragment的封装后基类,提供context给子类使用
*
* @author Graypn
*/
public
abstract
class
BaseFragment
extends
Fragment {
//根部view
private
View rootView;
protected
Context context;
private
Boolean hasInitData =
false
;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
context = getActivity();
}
@Override
public
View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if
(rootView ==
null
) {
rootView = initView(inflater);
}
return
rootView;
}
@Override
public
void
onActivityCreated(Bundle savedInstanceState) {
super
.onActivityCreated(savedInstanceState);
if
(!hasInitData) {
initData();
hasInitData =
true
;
}
}
@Override
public
void
onDestroyView() {
super
.onDestroyView();
((ViewGroup) rootView.getParent()).removeView(rootView);
}
/**
* 子类实现初始化View操作
*/
protected
abstract
View initView(LayoutInflater inflater);
/**
* 子类实现初始化数据操作(子类自己调用)
*/
public
abstract
void
initData();
/**
* 封装从网络下载数据
*/
protected
void
loadData(HttpRequest.HttpMethod method, String url,
RequestParams params, RequestCallBack<string> callback) {
if
(
0
== NetUtils.isNetworkAvailable(getActivity())) {
new
CustomToast(getActivity(), 无网络,请检查网络连接!,
0
).show();
}
else
{
NetUtils.loadData(method, url, params, callback);
}
}
}</string></span>
|
加入rootView,缓存加载后的view,如果有就不重新加载数据。
加入判断是否已经加载数据完成的标志变量,如果已经加载了数据,就不重新加载数据。
算是优雅的解决了优化的问题,希望能帮到有同样问题的同学。