Fragment 懒加载

 方法一、

 

        我们在遇到Activity嵌套Fragment的时候经常会遇到多个Fragment页面同时加载数据,一开始的时候就初始化很多页面,有的甚至进入页面的时候,会造成缓慢的现象,下面我们就针对这个问题做一下处理;

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

   代码如下:

 1     /* 
 2      * Date: 14-7-17 
 3      * Project: Access-Control-V2 
 4      */  
 5     package cn.irains.access_control_v2.common;  
 6       
 7     import android.support.v4.app.Fragment;  
 8       
 9     /** 
10      * Author: msdx (645079761@qq.com) 
11      * Time: 14-7-17 下午5:46 
12      */  
13     public abstract class LazyFragment extends Fragment {  
14         protected boolean isVisible;  
15         /** 
16          * 在这里实现Fragment数据的缓加载. 
17          * @param isVisibleToUser 
18          */  
19         @Override  
20         public void setUserVisibleHint(boolean isVisibleToUser) {  
21             super.setUserVisibleHint(isVisibleToUser);  
22             if(getUserVisibleHint()) {  
23                 isVisible = true;  
24                 onVisible();  
25             } else {  
26                 isVisible = false;  
27                 onInvisible();  
28             }  
29         }  
30       
31         protected void onVisible(){  
32             lazyLoad();  
33         }  
34       
35         protected abstract void lazyLoad();  
36       
37         protected void onInvisible(){}  
38     }  

 

       在LazyFragment,我增加了三个方法,一个是onVisiable,即fragment被设置为可见时调用,一个是onInvisible,即fragment被设置为不可见时调用。另外再写了一个lazyLoad的抽象方法,该方法在onVisible里面调用。你可能会想,为什么不在getUserVisibleHint里面就直接调用呢?

我这么写是为了代码的复用。因为在fragment中,我们还需要创建视图(onCreateView()方法),可能还需要在它不可见时就进行其他小量的初始化操作(比如初始化需要通过AIDL调用的远程服务)等。而setUserVisibleHint是在onCreateView之前调用的,那么在视图未初始化的时候,在lazyLoad当中就使用的话,就会有空指针的异常。而把lazyLoad抽离成一个方法,那么它的子类就可以这样做:

 1     public class OpenResultFragment extends LazyFragment{  
 2         // 标志位,标志已经初始化完成。  
 3         private boolean isPrepared;  
 4       
 5         @Override  
 6         public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
 7             Log.d(LOG_TAG, "onCreateView");  
 8             View view = inflater.inflate(R.layout.fragment_open_result, container, false);  
 9             //XXX初始化view的各控件  
10         isPrepared = true;  
11             lazyLoad();  
12             return view;  
13         }  
14       
15         @Override  
16         protected void lazyLoad() {  
17             if(!isPrepared || !isVisible) {  
18                 return;  
19             }  
20             //填充各控件的数据  
21         }  
22       
23     }  

 


在上面的类当中,我们增加了一个标志位isPrepared,用于标志是否初始化完成。然后在我们所需要的初始化操作完成之后调用,如上面的例子当中,在初始化view之后,设置 isPrepared为true,同时调用lazyLoad()方法。而在lazyLoad()当中,判断isPrepared和isVisible只要有一个不为true就不往下执行。也就是仅当初始化完成,并且可见的时候才继续加载,这样的避免了未初始化完成就使用而带来的问题。

在这里我对fragment的懒加载实现的介绍就到此为止,如果你有兴趣,可以基于此再深入探究,比如写一个带有缓初始化和可见时刷新的特性的Fragment。

原地址:http://blog.csdn.net/maosidiaoxian/article/details/38300627

 

 

方法二、

1、背景:为什么需要懒加载。  

    我们在做安卓项目的时候,经常会有一个使用场景:ViewPage与多个Fragment组合使用。  

  然而,viewpager有着预加载机制:默认一次加载当前页面前后两个页面,即使设置setOffLimit(0)也没有效果。  虽然预加载优化了app的体验效果,但是这样把我们看不到的页面的数据也加载了,大大降低了性能,浪费初始化资源。  

    这时候,我们就需要懒加载。  

2、什么是懒加载:懒加载的定义。

    当页面可见的时候,才加载当前页面。 没有打开的页面,就不会预加载。

    说白了,懒加载就是可见的时候才去请求数据。

3、实现方法

(1)关键点 

    主要的方法是Fragment中的setUserVisibleHint(),此方法会在onCreateView()之前执行,当viewPager中fragment改变可见状态时也会调用,当fragment 从可见到不见,或者从不可见切换到可见,都会调用此方法,使用getUserVisibleHint() 可以返回fragment是否可见状态。  

(2)注意事项

     <1>添加isPrepared参数。在系统调用onActivityCreated时设置为true,这时onCreateView方法已调用完毕(一般我们在这方法里执行findviewbyid等方法),确保 onLazyLoad()方法不会报空指针异常。

    <2>添加isLazyLoaded参数。确保ViewPager来回切换时BaseFragment的initData方法不会被重复调用,onLazyLoad在该Fragment的整个生命周期只调用一次,第一次调用onLazyLoad()方法后马上执行 isLazyLoaded = true。

    <3>getUserVisibleHint()会返回是否可见状态,这是fragment实现懒加载的关键,只有fragment 可见才会调用onLazyLoad() 加载数据。  

 

(3)demo 

            

 

posted @ 2016-11-12 11:06  张亚楠  阅读(1872)  评论(0编辑  收藏  举报