Android 解决Jetpack Navigation组件返回上一个Fragment时重走onCreateView、onViewCreated方法问题

使用navigate()方法跳转其他Fragment,再navigateUp()该Fragment出栈并返回上一个界面时,会重走上一个界面的onCreateView和onViewCreated()生命周期方法,导致View和数据的初始化代码逻辑会重新执行,每次返回都会刷新页面。并且如果上一页面中初始化逻辑较多,可能会导致返回时有明显卡顿。

问题场景:在项目中fragmentA界面的数据初始化操作是放在懒加载方法中执行,再跳转fragmentB界面并返回时,Afragment界面onViewCreated会重新执行View会重新初始化,但数据初始化只在懒加载方法中执行一次,这时上一fragment界面就会出现空白的情况。同时我在官方给出的Sunflower Demo中也验证了,同样是返回时上一fragment页面会重走。

问题原因:Navigation组跳转另一Fragment时,navigate()方法源码中使用的是ft.replace()方式,并不是add() hide() show(),这也导致了fragmentB覆盖fragmentA,返回时fragmentA是重新Create的。

public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
            @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {

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

// ...省略
}

解决方法:将NavHostFragment、FragmentNavigator类拷贝到项目中,修改FragmentNavigator中的navitgate()方法,并修改NavHostFragment中import FragmentNavigator的路径。

public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
            @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {

// ...省略
    if(mFragmentManager.getFragments().size()>0){                          
    ft.hide(mFragmentManager.getFragments().get(mFragmentManager.getFragments().size()-1));
            ft.add(mContainerId, frag);
    }else {
            ft.replace(mContainerId, frag);
    }
//      ft.replace(mContainerId, frag);
    ft.setPrimaryNavigationFragment(frag);

// ...省略
}

同时在设置NavHost时与使用NavHostFragment.findNavController(this).navigate(actionId, args)方法跳转时,导包使用项目中的NavHostFragment。

你可能感兴趣的:(Android开发中遇到的问题)