AndroidX下Navigation导航做单Activity多fragment类型下使用show/hide方式替代replace方式后返回上一级fragment生命周期不回调resume问题

解决方案先放最前面:找到覆写的FragmentNavigator类中public NavDestination navigate(@NonNull FragmentNavigator.Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras)这个方法,添加ft.setMaxLifecycle(lastFragment, Lifecycle.State.STARTED);如下面代码所示

if (mFragmentManager.getFragments().size() > 0) {
            Fragment lastFragment = mFragmentManager.getFragments().get(mFragmentManager.getFragments().size() - 1);
          ft.hide(lastFragment);
          //添加这行,保证fragment生命周期回调
          ft.setMaxLifecycle(lastFragment, Lifecycle.State.STARTED);
          if (frag.isAdded()) {
              ft.show(frag);
          } else {
              ft.add(mContainerId, frag);
          }
        } else {
            ft.replace(mContainerId, frag);
        }

//        ft.replace(mContainerId, frag);
        ft.setPrimaryNavigationFragment(frag);

Navigation库版本:2.3.2

有经验的开发者看见这个肯定知道这就是AndroidX下FragmentManager切换的生命周期设置方法。

最近开发的新项目使用了Navigation导航做单Activity应用,一开始被Navigation的replace切换fragment方式困扰,找到方法换成了show/hide方式,后续的开发阶段中又发现需要在生命周期回调中做些事情,之前的代码中返回上一级fragment时没有按照预期回调onResume,经过思考后(其实就是想起来以前做首页底部导航时的做法)找到了如上的解决方案,运行结果如下

最后附送找到的使用show/hide方式替换replace的fragment解决返回上一级全部重新走fragment生命周期困扰的方式,感谢广大网友。

1.复制androidx.navigation:navigation-fragment包中的FragmentNavigator类内容,找到下面的方法添加修改内容;

2.复制NavHostFragment类,将其中的FragmentNavigator类替换成上一步修改的FragmentNavigator类;

3.在使用导航的xml布局中把原本的NavHostFragment替换成我们修改后的NavHostFragment类。

 

@Nullable
    @Override
    public NavDestination navigate(@NonNull FragmentNavigator.Destination destination, @Nullable Bundle args,
                                   @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
        if (mFragmentManager.isStateSaved()) {
            Log.i(TAG, "Ignoring navigate() call: FragmentManager has already saved its state");
            return null;
        }
        String className = destination.getClassName();
        if (className.charAt(0) == '.') {
            className = mContext.getPackageName() + className;
        }
        final Fragment frag = instantiateFragment(mContext, mFragmentManager, className, args);
        frag.setArguments(args);
        final FragmentTransaction ft = mFragmentManager.beginTransaction();

        int enterAnim = navOptions != null ? navOptions.getEnterAnim() : -1;
        int exitAnim = navOptions != null ? navOptions.getExitAnim() : -1;
        int popEnterAnim = navOptions != null ? navOptions.getPopEnterAnim() : -1;
        int popExitAnim = navOptions != null ? navOptions.getPopExitAnim() : -1;
        if (enterAnim != -1 || exitAnim != -1 || popEnterAnim != -1 || popExitAnim != -1) {
            enterAnim = enterAnim != -1 ? enterAnim : 0;
            exitAnim = exitAnim != -1 ? exitAnim : 0;
            popEnterAnim = popEnterAnim != -1 ? popEnterAnim : 0;
            popExitAnim = popExitAnim != -1 ? popExitAnim : 0;
            ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim);
        }
        //-------------------修改的内容开始------------------------------------
        if (mFragmentManager.getFragments().size() > 0) {
            Fragment lastFragment = mFragmentManager.getFragments().get(mFragmentManager.getFragments().size() - 1);
            ft.hide(lastFragment);
            ft.setMaxLifecycle(lastFragment, Lifecycle.State.STARTED);
            if (frag.isAdded()) {
                ft.show(frag);
            } else {
                ft.add(mContainerId, frag);
            }
        } else {
            ft.replace(mContainerId, frag);
        }

//        ft.replace(mContainerId, frag);
        ft.setPrimaryNavigationFragment(frag);
        //--------------------修改内容结束---------------------------------------

        final @IdRes int destId = destination.getId();
        final boolean initialNavigation = mBackStack.isEmpty();
        // TODO Build first class singleTop behavior for fragments
        final boolean isSingleTopReplacement = navOptions != null && !initialNavigation
                && navOptions.shouldLaunchSingleTop()
                && mBackStack.peekLast() == destId;

        boolean isAdded;
        if (initialNavigation) {
            isAdded = true;
        } else if (isSingleTopReplacement) {
            // Single Top means we only want one instance on the back stack
            if (mBackStack.size() > 1) {
                // If the Fragment to be replaced is on the FragmentManager's
                // back stack, a simple replace() isn't enough so we
                // remove it from the back stack and put our replacement
                // on the back stack in its place
                mFragmentManager.popBackStack(
                        generateBackStackName(mBackStack.size(), mBackStack.peekLast()),
                        FragmentManager.POP_BACK_STACK_INCLUSIVE);
                ft.addToBackStack(generateBackStackName(mBackStack.size(), destId));
            }
            isAdded = false;
        } else {
            ft.addToBackStack(generateBackStackName(mBackStack.size() + 1, destId));
            isAdded = true;
        }
        if (navigatorExtras instanceof FragmentNavigator.Extras) {
            FragmentNavigator.Extras extras = (FragmentNavigator.Extras) navigatorExtras;
            for (Map.Entry<View, String> sharedElement : extras.getSharedElements().entrySet()) {
                ft.addSharedElement(sharedElement.getKey(), sharedElement.getValue());
            }
        }
        ft.setReorderingAllowed(true);
        ft.commit();
        // The commit succeeded, update our view of the world
        if (isAdded) {
            mBackStack.add(destId);
            return destination;
        } else {
            return null;
        }
    }

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值