Fragment的setUserVisibleHint方法实现

转载 2015年07月10日 15:17:15

我们在做应用开发的时候,一个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。


Fragment的setUserVisibleHint详解

Android应用开发过程中,ViewPager同时加载多个fragment,以实现多tab页面快速切换, 但是fragment初始化时若加载的内容较多,就可能导致整个应用启动速度缓慢,影响用户体验。...
  • czhpxl007
  • czhpxl007
  • 2016年04月28日 20:25
  • 17425

setUserVisibleHint-- fragment真正的onResume和onPause方法

现在越来越多的应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,如下图就是fragment的生命周期 但是fragment和activit...
  • jav_imba
  • jav_imba
  • 2015年08月11日 13:30
  • 17152

Fragment的setUserVisibleHint方法实现

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在...
  • qq_18353977
  • qq_18353977
  • 2015年07月10日 15:17
  • 451

关于Fragment的setUserVisibleHint() 方法

在写Android项目过程中,不可避免的会遇到用Fragment当作一个界面,尤其是当使用ViewPager 配合使用Fragment,更是头疼,我就是遇到了这个问题,所以大概的研究了一下,来给大家分...
  • Ourxiaolei
  • Ourxiaolei
  • 2016年10月25日 18:12
  • 2341

ViewPager+Fragment setUserVisibleHint取消预加载(延迟加载)

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载V...
  • newsa
  • newsa
  • 2016年02月19日 09:07
  • 1834

Fragment的setUserVisibleHint方法实现懒加载,但setUserVisibleHint 不起作用?

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在...
  • H_shaohui
  • H_shaohui
  • 2016年12月27日 10:54
  • 576

Fragment中setUserVisibleHint 方法调用问题

都知道在Fragment与ViewPager配合使用的时候 使用setUserVisibleHint 方法来延迟数据加载。今天我测试手动add和hide 发现 Fragment的setUserVisi...
  • ohanweb123
  • ohanweb123
  • 2016年06月16日 13:37
  • 2623

Android使用Fragment的setUserVisibleHint方法实现延时加载

大家开发Android的APP的时候,应该都是用过Fragment。 Fragment使用起来非常方便,灵活。在ViewPage中PageAdapter来管理所有的Fragment即可。       ...
  • njtuzhang
  • njtuzhang
  • 2016年08月17日 10:29
  • 715

fragment setUserVisibleHint onHiddenChanged方法

调用 hide show 方法是,下面的方法会调用 if (currentFragment != to) { currentFragment = to; FragmentTransaction ...
  • fumeidonga
  • fumeidonga
  • 2016年04月01日 13:55
  • 3012

Fragment中的setUserVisibleHint()方法调用

使用Fragment的时候难免会遇到想在视图可见与不可见之中做些操作,此时通常会想到类似Activity中的onResume()和onPause()方法。Fragment中也确实有这两个方法,然而亲测...
  • sunnyskybluesea
  • sunnyskybluesea
  • 2015年07月03日 11:08
  • 7715
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Fragment的setUserVisibleHint方法实现
举报原因:
原因补充:

(最多只允许输入30个字)