踩坑日记——多层嵌套Fragment的显示回调

阅读本文大概需要3分钟

引言

Fragment是在Android3.0后引入的一个新API,它的出现是为了适配平板电脑的大屏幕。
同时,它也能缓解Activity任务过多的问题,以及处理在不同屏幕上UI组件的布局问题。
因此随着业务开发一点一点的累积;Fragment在我们的开发中占据着越来越重要的地位。

在复杂的页面设计中把控Fragment的生命周期回调显得尤为重要。本篇主要解决——在Fragment多层嵌套时,如何获取到Fragment在屏幕中显示的回调

多层嵌套的Fragment

踩坑日记——多层嵌套Fragment的显示回调_第1张图片

如上图,这个界面由一个Activity中容纳了4个Tab Fragment,其中Fragment_3容纳了一个ViewPager+3个Fragment(分别为Fragment_A、Fragment_B、Fragment_C)。那么问题就产生了,我们想要在Fragment在显示到屏幕时实现一些逻辑,这个回调时机是什么时候?该如何做呢?这里主要分为3种情况。

  1. 当我们在Fragment_3中左右滑动,每个Fragment显示时的回调如何获取呢?(范围:Fragment容器内)
  2. 当我们滑动到Fragment_C,点击了底部Tab切换到1Fragment_1再切换回Fragment_3,如何获取到Fragment_C的显示回调?(范围:Activity容器内)
  3. 当我们滑动到Fragment_C按了Home键再返回当前app时,又如何获取?跳转其他Activity再返回时呢?(范围:整个App)

知识前奏

1.Fragment的生命周期

简单提一下Fragment的生命周期,Fragment是拥有和Activity一致的生命周期,如下图所示:

踩坑日记——多层嵌套Fragment的显示回调_第2张图片

2.关于setUserVisibleHint与getUserVisibleHint

在ViewPager + Fragment 配合使用的时候,ViewPager会同时加载多个Fragment,也可以设置加载数。

当滑动Viewpager显示该Fragment时系统会调用setUserVisibleHint()这个方法;我们可以复写这个方法实现一些逻辑;但这个方法只能实现这一种情况。

setUserVisibleHint()仅在当前Fragment初始化以及在当前ViewPager中切换的时候才会回调。
源码如下:

/**
*
*  @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
*                         false if it is not.
*/
public void setUserVisibleHint(boolean isVisibleToUser) {
   if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
       mFragmentManager.performPendingDeferredStart(this);
   }
   mUserVisibleHint = isVisibleToUser;
   mDeferStart = !isVisibleToUser;
}

/**
 * @return The current value of the user-visible hint on this fragment.
 * @see #setUserVisibleHint(boolean)
 */
public boolean getUserVisibleHint() {
    return mUserVisibleHint;
}

解决问题

核心问题:在任何时候,如何获取到Fragment_C显示给用户时的回调?

第一种情况切换内部Fargment,也就是ViewPager中Fragment的切换就直接复用setUserVisibleHint()就可以解决了。

这里需要特别注意一点,在这个方法中执行延时逻辑时,判断当前界面是否显示给用户的方法,最好不要使用getUserVisibleHint()这个方法;这个方法返回值仅仅是当前Fragment在ViewPager是否显示的值,也就是说我们滑动到当前页面,系统回调了setUserVisibleHint()并把值设置为true,这时我们按了home键或者点击底部tab跳转到其他Fragment,当前getUserVisibleHint()值还是true。这并不是我们所需要的结果。操作生命周期Log打印日志,如下图所示:
踩坑日记——多层嵌套Fragment的显示回调_第3张图片

第二种情况切换外部Fragment,在4个Tab+Fragment中,如上述界面截图,Fragment_3中嵌套Viewpager+Fragment;底部Tab切换时,如何获取到Fragment_C显示给用户的回调?

解决方法:复写Fragment_3中的onHiddenChanged方法,同时也要复写在Fragment_C的onHiddenChanged()方法,并处理逻辑.如下图所示(Fragment_3把当前显示的回调传递给Fragment_C):

踩坑日记——多层嵌套Fragment的显示回调_第4张图片

第三种情况切换Activity,在按home键或者 跳转了其他Activity,再返回当前时,如何获取回调?

解决方法:复写当前onResume(),isVisible()和getUserVisibleHint()等判断。

你可能感兴趣的:(android)