上次写了一个问答项目,用的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,如果有就不重新加载数据。
加入判断是否已经加载数据完成的标志变量,如果已经加载了数据,就不重新加载数据。
算是优雅的解决了优化的问题,希望能帮到有同样问题的同学。