Fragment的生命周期

Fragment可以用来解决不同屏幕分辨率的适配问题,跟Activity一样,它有自己的生命周期,不过貌似比Activity复杂了点:

这里写图片描述

使用Fragment有两种方法,可以在布局文件中直接使用fragment节点将一个Fragment加载到布局中,也可以使用FragmentManager动态管理布局上的Fragment,而动态管理Fragment,一般是这样子:

        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        //ft.add(fragment, tag)
        //ft.remove(fragment)
        //ft.replace(containerViewId, fragment)
        //ft.show(fragment)
        //ft.hide(fragment)

        ft.commit();

注意需要弄清楚执行不同的操作时会回调那些生命周期函数。
(1)add:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
(2)remove:onPause->onStop->onDestroyView->onDestroy->onDetach
(3)replace:实际就是先remove旧的再add新的。
(4)show,hide:不回调任何生命周期函数

Fragment与Activity间的生命周期关系

这里写图片描述

如果在在布局文件中使用静态指定一个fragemnt节点,不使用FragmentManager对其进行管理,那么该Fragment与Activity的生命周期回调函数调用顺序为:
(1)Fragment的onAttach,onCreate,onCreateView是在Activity的onCreate中调用的。
(2)Activity的onCreate执行完就调用Fragment的onActivityCreated。
(3)调用onStart,onResume时先调Activity的再调Fragment;调用onPause,onStop时先调Fragment的再调用Activity。
(4)接下来调用Fragment的onDestroyView,onDestroy,onDetach,最后才调Activity的onDestroy。

Fragment嵌套在ViewPager中时的生命周期

我们有时会使用ViewPager+Fragment实现多屏滑动效果,由于ViewPager有缓存和预加载功能,所以这些Fragment的生命周期也会有所不同。
假设有一个ViewPager嵌套了6个Fragment以实现左右滑动的界面效果,6个Fragment从左到右依次为A,B,C,D,E和F。则:
(1)首次进入界面,看到的是A,这时A就会回调onAttach到onResume一系列的生命周期函数,由于ViewPager有预加载功能,它会预先加载当前Fragment左右mOffscreenPageLimit个Fragment,mOffscreenPageLimit默认为1,因此这时B也会回调onAttach到onResume一系列的生命周期函数。
(2)接着向右滑动一页,现在看到的是B,同样ViewPager会去预加载当前Fragment左右mOffscreenPageLimit个Fragment,由于左边是A刚才已经加载了,因此不用加载A,右边是C还没有被加载,那么就加载C,这时C从onAttach到onResume一系列的生命周期函数会被调用。
(3)继续向右滑动一页,现在看到的是C,同样道理去加载D。不过这时A已经偏离当前显示的Fragment C超过mOffscreenPageLimit了,那么A的View就会被销毁,会回调onPause到onDestroyView一系列回调函数。
(4)如果这时再向左滑回来,此时看到B,那么又会调用A的onCreateView,onActivityCreated,D的onPause,onStop,onDestroyView,A的onStart,onResume。
(5)最后销毁ViewPager时,所有被加载的Fragment都会调用相应回调函数直到onDetach为止。

总的来说:ViewPager会预加载当前Fragment左右mOffscreenPageLimit个Fragment,而距离更远的Fragment如果之前被加载过就会被销毁掉,防止占用太多内存。

mOffscreenPageLimit相关说明:
在ViewPager源码中mOffscreenPageLimit默认为1:

private static final int DEFAULT_OFFSCREEN_PAGES = 1;
......
private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES;

可以调用setOffscreenPageLimit设置预加载和缓存最大偏移量:

    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                    DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

可以看到mOffscreenPageLimit必须大于等于1,所以如果我们为了提高响应速度,避免占用过多内存不想要预加载和缓存那些看不到的Fragment,可以改写ViewPager相关代码实现懒加载。

本博客已停止更新,转移到微信公众号上写文章,欢迎关注:Android进阶驿站
Android进阶驿站

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值