我改进了 Umut ADALI 的答案:
/**
* Created by Nooi on 12,February,2021
*/
@Navigator.Name("fragment")
class PersistentFragmentNavigator(
persistentClasses : Set<KClass<out Fragment>>,
context : Context,
manager : FragmentManager,
containerId : Int
) : FragmentNavigator(context, manager, containerId) {
private val navigatorHandler = PersistentNavigatorHandler(persistentClasses, manager, containerId)
init {
navigatorHandler.addTopFragmentIfRequired()
}
override fun instantiateFragment(context : Context, fragmentManager : FragmentManager, className : String, args : Bundle?) : Fragment {
return navigatorHandler.instantiateFragment(className) {
super.instantiateFragment(context, fragmentManager, className, args)
}
}
}
private class PersistentNavigatorHandler(
private val persistentClasses : Set<KClass<out Fragment>>,
private val manager : FragmentManager,
private val containerId : Int
) {
private val instances = mutableMapOf<String, Fragment>()
fun addTopFragmentIfRequired() {
manager.findFragmentById(containerId)
?.takeIf { fragment ->
persistentClasses.any { it.qualifiedName == fragment.javaClass.name }
}
?.let { fragment ->
instances[fragment.javaClass.name] = fragment
}
}
fun instantiateFragment(className : String, superCall : () -> Fragment) : Fragment {
return instances[className] ?: superCall.invoke().also { fragment ->
if (persistentClasses.any { it.qualifiedName == className }) {
instances[className] = fragment
}
}
}
}
在获得navController和navHostFragment之后,将此代码添加到您的活动的onCreate中:
navController.navigatorProvider.addNavigator(PersistentFragmentNavigator(
persistentClasses = setOf(SomePersistentFragment::class),
context = this,
manager = navHostFragment.childFragmentManager,
containerId = R.id.nav_host_fragment
))
导航将与图形正常工作,但是当再次导航到标记为持久的片段时,会恢复之前的片段实例。在构建任何选项卡导航时非常有用。