博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为Fragment增加新的生命周期,并实现管理
阅读量:5840 次
发布时间:2019-06-18

本文共 2557 字,大约阅读时间需要 8 分钟。

1.  背景知识

    ViewPager+Fragment实现滑动标签页时,默认情况下,Fragment的生命周期是由FragmentPagerAdapter和Activity共同管理的。

(1) Activity维持在onResume状态时,Fragment的生命周期主要由FragmentPagerAdapter进行管理。进行了预加载的Fragment会处于onResume状态(即使没有变成可操作),预加载多少个Fragment,可以通过    ViewPager::setOffscreenPageLimit()函数进行设置。
   在切换滑动标签页时,已经预加载的Fragment的生命周期不会被触发改变,仍然是onResume。

(2) 当Activity的生命周期发生变化时,所有已经预加载的Fragment的生命周期与Activity保持一致。
   Fragment生命周期与Activity生命周期的关系(主要看onResume和onPause):
     onResume执行顺序 :
        Activity::onResume() -> Fragment::onResume. (Synchronously)
     onPause执行顺序 :
        Fragment::onPause -> Activity::onPause.     (Synchronously)

2.项目需求

    在我们的项目中,因为既需要同时加载多个Fragment, 又需要在Fragment变为可见时做一些事情,不可见时又做一些事情(如切换到该标签页时进行视频播放,退出该标签页时关闭播放),因此,继承Fragment,我们实现自己的MyFragment,在MyFragment中增加了另外两个生命周期: onEnter() (fragment变为可见时回调), onExit()(fragment变为不可见时回调)。这样,我们就可以在onEnter中做开始播放的操作,在onExit中停止播放。

3.解决方案

    根据需求中的描述,增加了两个生命周期后,完整的Fragment的生命周期就变为:

         onCreate()->onCreateView()->onStart()->onResume()->onEnter()->onExit()->onPause()->onStop()->onDestroyView()->onDestroy().
    为了确保生命周期的顺序,需要继承FragmentStatePagerAdapter实现自己的MyFragmentStatePagerAdapter, 重写setPrimaryItem()函数来控制Fragment的生命周期。实现如下:
             MyFragmentStatePagerAdapter::setPrimaryItem(ViewGroup container, int position, Object object) {
                      MyFragment myFragment = (MyFragment)object;
                      if ((myFragment != NULL) && myFragment.isResumed()) {
                          if (myFragment != mpCurrentPrimaryItem) {
                              if (mpCurrentPrimaryItem) {
                                   mpCurrentPrimaryItem.onExit();
                                   mpCurrentPrimaryItem = NULL;
                              }
                              if (myFragment) {
                                  myFragment.onEnter();
                                  mpCurrentPrimaryItem = myFragment;
                             }
                         }
                    }
              }

 

  • MyFragment::onEnter会在几种情况下被执行:

(1)  当Activity是第一次启动时,进入到onResume, 调用ViewPager::setAdapter()函数第一次给ViewPager设置MyFragmentStatePagerAdapter时, 会回调到setPrimaryItem(), 从而使MyFragment进入onEnter.

(2)  若Activity不是第一次进入onResume, 就不能通过ViewPager::setAdapter使fragment进入onEnter了。这时需要在Activity::onResume中给MyFragment设置一个需要进入onEnter的标记,在MyFragment随后进入onResume时(背景知识有说明),找到MyFragment所在的ViewPager,并获取Adapter, 然后调用setPrimaryItem()使自己进入onEnter.
(3)  切换页面时,由MyFragmentStatePagerAdapter::setPrimaryItem()执行。

  • MyFragment::onExit会在两种情况下被执行:

(1) 一种是在Activity执行onPause之后,MyFragmentStatePagerAdapter::setNonePrimaryItem()使MyFragment执行onExit().

MyFragmentStatePagerAdapter::setNonePrimaryItem() {
    if (mpCurrentPrimaryItem) {
        mpCurrentPrimaryItem.onExit();
        mpCurrentPrimaryItem = NULL;
    }
}
需要说明的一点是,由于在Activity onPause之前,已经加载的Fragment会先执行onPause, 所以这种情况下不能确保onExit在onPause之前,这时MyFragmnet生命周期为:onResume()->onEnter()->onPause()->onExit()->onStop(). (这点在我们项目中没有影响)
(2) 第二种是在切换页面时,由MyFragmentStatePagerAdapter::setPrimaryItem()实现。

转载于:https://www.cnblogs.com/Jackwen/p/4126591.html

你可能感兴趣的文章
vue-cli多页面
查看>>
进程和线程
查看>>
iOS Foundation框架简介 -1.常用结构体的用法和输出
查看>>
java--迭代(三)foreach解析与字节码
查看>>
libevent reference Mannual I
查看>>
《mysql必知必会》读书笔记--安全管理及数据库维护
查看>>
eclipse创建Maven父子结构Maven项目
查看>>
Python 太糟糕了?开发者总结了 8 大原因
查看>>
Spring中注入基本类型
查看>>
aws devops
查看>>
Android 中文API (33) —— Checkable
查看>>
脚本方式安装 IIS7
查看>>
Oracle password expire notices
查看>>
C++异常处理 - try,catch,throw,finally的用法
查看>>
稳扎稳打Silverlight(12) - 2.0外观之样式, 模板, 视觉状态和视觉状态管理器
查看>>
Linux技巧汇总
查看>>
Linux下多播编程<一>【十全十美】
查看>>
怎样给RCP程序添加依赖的JAR包
查看>>
嵌入式应用MPU前景看好
查看>>
动态路由协议
查看>>