资讯专栏INFORMATION COLUMN

Fragment的生命周期以及懒加载的简单实现

andycall / 2814人阅读

摘要:首先定义一个基类重写所有生命周期方法并打印假如现在有五个子类通过左右滑动切换刚进入页面时

首先定义一个基类Fragment,重写所有生命周期方法,并打印log.
假如现在有五个子类Fragment通过ViewPager左右滑动切换.
刚进入页面时:

  first----------setUserVisibleHint: false
  second---------setUserVisibleHint: false
  first----------setUserVisibleHint: true
  first----------onAttach
  first----------onCreate
  second----------onAttach
  second----------onCreate
  first-----------onCreateView
  first-----------onActivityCreated
  first-----------onStart
  first-----------onResume
  second-----------onCreateView
  second-----------onActivityCreated
  second-----------onStart
  second-----------onResume

ViewPager默认预先加载一个Fragment.当Fragment对用户可见时,setUserVisibleHint参数为true,否则为false.
从上面的log可以看到,初始化页面时,预先走了第二个fragment的setUserVisibleHint方法,但是此时所有的fragment对用户还不可见,所以两个setUserVisibleHint的参数都为false.当第一个fragment对用户可见时,继续走了setUserVisibleHint,参数为true,而第二个fragment对用户不可见,参数为false,就没有再次走setUserVisibleHint.而后是交替加载两个fragment的生命周期直到onResume,从这里可以看出onResume不能判定fragment是否对用户可见.
所以可以在setUserVisibleHint中根据其参数判定某个Fragment是否对用户可见.

然后滑动,使第二个fragment可见,隐藏第一个fragment.其生命周期流程如下:

third-----------setUserVisibleHint: false
first-----------setUserVisibleHint: false
second-----------setUserVisibleHint: true
third----------onAttach
  third----------onCreate
third-----------onCreateView
  third-----------onActivityCreated
  third-----------onStart
  third-----------onResume

同样地,先将下一个fragment和上一个frag的setUserVisibleHint的参数重置为false,再将自身的置为true,上面的结论是正确的.并且初始化下一个fragment的生命周期,并没有销毁上一个fragment的生命周期,同时也没有再走自己别的生命周期方法.

从第二个fragment滑动到第三个fragment,生命周期流程如下:

  forth-----------setUserVisibleHint: false
  second-----------setUserVisibleHint: false
  third-----------setUserVisibleHint: true
  forth----------onAttach
  forth----------onCreate
  first-----------onPause
  first-----------onStop
  first-----------onDestroyView
  forth-----------onCreateView
  forth-----------onActivityCreated
  forth-----------onStart
  forth-----------onResume

在这里销毁了第一个fragment的view,走到了onDestroyView.
fragment滑动切换时,会销毁相隔前一个的view,这个相隔前一个不是位置上的相隔前一个,而是时间上的(其实是fragment任务管理栈,先进先出).

总结以上的结论:
1:通过setUserVisibleHint的参数来判断当前fragment是否可见.
2:滑动切换到某个fragment,会预加载下一个fragment的生命周期,销毁相隔前一个的fragment的view(onDestroyView),并且将自己的setUserVisibleHint参数置为true,不会再走自己的生命周期方法(被前一个fragment预加载了).

懒加载

这里所说的懒加载就是只有当前fragment处于可见时,才加载数据,否则不加载.fragment默认是预加载下一个页面数据的.

从上面来看,是不是只要在setUserVisibleHint中根据参数来判断是否加载数据就可以了?不是的,要考虑到当前页面的View是否加载完成.
定义一个成员变量,来标记view是否创建完成

 boolean isViewCreated = false;

在onCreateView中将isViewCreated置为true,onDestroyView中置为false.

初始化页面时,第一个FragmentsetUserVisibleHint参数为true时,其onCreateView方法还没走到,变量isViewCreated = false.这时我们在onActivityCreated中做加载数据的判断

  @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState){
      super.onActivityCreated(savedInstanceState);
      if(isViewCreated && getUserVisibleHint()){
        loadData();
      }
    }

当滑动到下一个页面时,不会再次走这个页面的生命周期方法,并且其onCreateView方法已经加载完毕,所以在setUserVisibleHint中做加载数据

 @Override
 public void setUserVisibleHint(boolean isUserVisibleHint){
   if(isUserVisibleHint && isViewCreated){
     loadData();
  }
}
关闭懒加载

定义一个boolean字段来开启/关闭懒加载

 /*是否开启懒加载,默认开启*/
    protected boolean useLazyMode = true;

需要在onActivityCreatedsetUserVisibleHint中处理数据加载.

 @Override
 public void setUserVisibleHint(boolean isUserVisibleHint){
   if(isUserVisibleHint && isViewCreated&&useLazyMode ){
     loadData();
  }
}

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState){
      super.onActivityCreated(savedInstanceState);
      if (useLazyMode){
      //当前页面可见时才去加载数据
           if (isViewCreated&&getUserVisibleHint()){
               loadData();
           }
       }else {
       //预加载下一个页面数据
           if (isViewCreated){
               loadData();
           }
       }
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14618.html

相关文章

  • ViewPager加载极致优化

    摘要:最后,当一次更新添加和或移除完成之后将会调用来通知提交关联和或取消关联的操作。懒加载的实现弊端概念当需要时才加载,加载之后一直保持该对象。而且为了实现滑动效果,都是预加载左右两侧的页面。预加载的预加载机制。 目录介绍 01.ViewPager简单介绍 02.ViewPager弊端分析 03.ViewPager预加载 04.ViewPager部分源码 05.懒加载出现问题 06.如何实...

    gotham 评论0 收藏0
  • Android基础:Fragment,看这篇就够了

    摘要:也有类似的栈,称为回退栈,回退栈是由管理的。为的参数,通过能找到回退栈的特定元素,可以为或者,表示只弹出该元素以上的所有元素,表示弹出包含该元素及以上的所有元素。是异步执行的,是丢到主线程的执行,是同步版本。 欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 由 天天P图攻城狮 发布在云+社区 作者简介:damonxia(夏正冬),天天P图Android工程师 下文中Demo的源...

    littleGrow 评论0 收藏0
  • Fragment新功能,setMaxLifecycle了解一下

    摘要:前言写上一篇软文时,我发现最新的代码淘汰了方法,转而支持用方法,言外之意是设置最大生命周期,懂行的人应该知道,一直都是无法直接设置生命周期,必须通过方法间接干预,本来就此功能,简单介绍一下的原理和上手效果阅读指南本文基于版本的进行,也是支前言 写上一篇ViewPager2软文时,我发现最新的Fragment代码淘汰了setUserVisibleHint方法,转而支持用setMaxLifecy...

    233jl 评论0 收藏0
  • ViewPager2重大更新,支持offscreenPageLimit

    摘要:前言最近发布了版本,新增功能,该功能在上并不友好,现在官方将此功能延续下来,这回是骡子是马呢赶紧拉出来溜溜阅读指南内容基于版本讲解,由于正式版还未发布,如有功能变动有劳看官指出内容重点介绍的特性和预加载机制,另外包括的状态和的生命周前言 最近ViewPager2发布了1.0.0-alpha04版本,新增offscreenPageLimit功能,该功能在ViewPager上并不友好,现在官方将...

    番茄西红柿 评论0 收藏0
  • ViewPager2重大更新,支持offscreenPageLimit

    摘要:前言最近发布了版本,新增功能,该功能在上并不友好,现在官方将此功能延续下来,这回是骡子是马呢赶紧拉出来溜溜阅读指南内容基于版本讲解,由于正式版还未发布,如有功能变动有劳看官指出内容重点介绍的特性和预加载机制,另外包括的状态和的生命周前言 最近ViewPager2发布了1.0.0-alpha04版本,新增offscreenPageLimit功能,该功能在ViewPager上并不友好,现在官方将...

    aervon 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<