Fragment详解

本文详细解析了Android中Fragment的生命周期,包括与Activity的关系、生命周期回调方法及常见流程。同时,深入探讨了Fragment的懒加载机制,介绍了如何利用setUserVisibleHint()方法实现数据的按需加载。

1.定义

碎片,依赖于Activity,不能独立存在。Fragment有自己的生命周期,一个Activity可以有多个Fragment,一个Fragment可以被多个Activity复用

2.生命周期

Fragment必须是依赖于Activity存在的,它的生命周期受Activity的生命周期影响,两者的生命周期如上图所示。

2.1回调方法

2.1.1与Activity相同的生命周期回调方法

onCreate()     //创建fragment时回调

onStart()     //启动fragment时回调

onResume()    //恢复fragment时回调

onPause()     //暂停fragment时回调

onStop()      //停止fragment时回调

onDestroy()   //销毁fragment时回调

2.1.2比Activity多5个生命周期回调方法

onAttach(Activity);  // 与Activity关联

onCreateView(LayoutInflater,ViewGroup,Bundle);  //  创建Fragment视图

onActivityCreate(bundle);  //  关联的Activity的onCreate();方法返回时调用

onDestoryView();  //  与onCreateView相对应,Fragment移除时调用

onDetach();  // 与onAttach()相对应,与Activity的关联取消

2.2常见的生命周期流程

1.Activity加载Fragment时:

onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

2.Fragment所在的Activity可见,但不获得焦点,弹出一个对话框:onPause

3.对话框关闭,Activity又获取焦点时:OnReusme

4.替换Fragment,并调用addToBackStack()添加到Back栈中,此时的Fragment没有销毁

onPause -> onStop -> onDestoryView

5.按下键盘的回退键,Fragment再次显示出来时

onCreateView -> onActivityCreated -> onStart ->onResume

6.进入销毁状态时

onPause -> onStop -> onDestoryView -> onDestory -> onDetach

2.3Fragment正常的一生

onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

->onPause -> onStop -> onDestoryView -> onDestory -> onDetach

3.懒加载

3.1什么是懒加载

当Fragment可见时才会加载数据。我们会把ViewPage与Fragment组合使用,Viewpager有着预加载机制:默认一次加载当前页面前后两个页面,即使设置setOffLimit(0)也没有效果,这样把我们看不到的页面数据也加载了,大大降低了性能,浪费初始化资源。

3.2懒加载的主要方法

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    }

设置Fragment可见或者不可见时会调用setUserVisibleHint(),isVisibleToUser表示Fragment是否可见

3.3懒加载实现的方式


public abstract class LazyFragment extends Fragment {

    /**
     * 是否初始化过布局
     */
    private boolean isFirst;

    /**
     * 当前Fragment是否可见
     */
    private boolean isVisible;

    /**
     * 是否加载过数据,确保fragment来回切换时不会重复加载数据
     */
    protected boolean isLoad;


    ....省略其他代码...

    /**
     * 不是表示fragment所依赖的activity创建完成,fragment所依赖的activity的onCreate方法执行结束
     *
     * @param savedInstanceState
     */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isFirst= true;

        init();

        //第一个默认显示的Fragment加载数据   在这里需要加载一次
        initLazyData();
    }


    /**
     * 设置Fragment可见或者不可见时会调用此方法。isVisible表示Fragment是否可见,在该方法里面也可以通过调用getUserVisibleHint()
     * 获得Fragment的状态是可见还是不可见的,如果可见则进行懒加载操作。
     * <p>
     * 此方法比onCreate()更早调用的,所以如果在setUserVisibleHint()要实现懒加载的话,
     * 就必须要确保View以及其他变量都已经初始化结束,避免空指针。
     * <p>
     * setUserVisibleHint(boolean isVisibleToUser)方法是比onCreate更早调用的,
     * 但是我们一般在加载数据时,都会在数据加载完成时进行UI更新,所以这就有了一个问题,假如拉取数据是秒回,
     * 但是我们还没有进行UI绑定,或者是Adapter初始化等,那么我们就无法更新UI了,所以Fragment给我们提供了
     * 另一个方法getUserVisibleHint(),它就是用来判断当前Fragment是否可见
     *
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        //获得Fragment的状态是可见还是不可见的
       /* if (getUserVisibleHint()) {
            isVisible = true;
            initLazyData();
        }*/

        this.isVisibleToUser = isVisible;
        if (isVisible) {
            initLazyData();
        }
    }


    private void initLazyData() {
        if (isVisible && isFirst && !isLoad) {
            initData();
            isLoad = true;
        }
    }

    /**
     * 判断懒加载条件
     *
     */
    public void initLazyData(boolean isRefresh) {
        if (isVisible && isFirst && (!isLoad || isRefresh)) {
            initData();
            isLoad= true;
        }
    }
    
   @Override
    public void onDestroyView() {
        super.onDestroyView();

        isFirst = false;
        isLoad = false;
    }

    
    ....省略其他代码...

}

     

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值