Fragment的setUserVisibleHint方法实现

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源。这样的结果,我们当然不会满意。那么,能不能做到当切换到这个fragment的时候,它才去初始化呢?

注释:setUserVisibleHint每次fragment显示与隐藏都会调用,他的调用顺序由于onCreate,所以需要一些常量进行判断

package cn.irains.access_control_v2.common;
import android.support.v4.app.Fragment;


public abstract class LazyFragment extends Fragment {
     protected boolean isVisible;
     /**
      * 在这里实现Fragment数据的缓加载.
      * @param isVisibleToUser
      */
     @Override
     public void setUserVisibleHint(boolean isVisibleToUser) {
         super .setUserVisibleHint(isVisibleToUser);
         if (getUserVisibleHint()) {
             isVisible =  true ;
             onVisible();
         else  {
             isVisible =  false ;
             onInvisible();
         }
     }
     protected void onVisible(){
         lazyLoad();
     }
     protected abstract void lazyLoad();
     protected void onInvisible(){}
}

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

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

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

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


这个是设置viewpager保留多少个显示界面

1
pager.setOffscreenPageLimit( 3 );


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值