使用导航组件时,片段savedInstanceState 始终为空

15 android android-fragments android-navigation android-bottomnav android-architecture-components

目前,我正在玩带有底部导航栏的 Android 导航组件。在玩的过程中,我意识到两个事实:

  • 片段总是被重新创建(onCreate, onViewCreated,onViewDestroyed一旦用户导航到另一个片段就会被调用)
  • savedInstanceState始终为空(在onCreateonViewCreated等等)

第一个问题可以通过使用 custom 修复,FragmentNavigator如果片段已经存在,它将重用

package am.chamich.apps.advancedbottomnavigation.navigator

import android.content.Context
import android.os.Bundle
import androidx.navigation.NavDestination
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
import androidx.navigation.fragment.FragmentNavigator


@Navigator.Name("retain_state_fragment")
class RetainStateFragmentNavigator(
    private val context: Context,
    private val manager: androidx.fragment.app.FragmentManager,
    private val containerId: Int
) : FragmentNavigator(context, manager, containerId) {

    override fun navigate(
        destination: Destination,
        args: Bundle?,
        navOptions: NavOptions?,
        navigatorExtras: Navigator.Extras?
    ): NavDestination? {
        val tag = destination.id.toString()
        val transaction = manager.beginTransaction()

        val currentFragment = manager.primaryNavigationFragment
        if (currentFragment != null) {
            transaction.detach(currentFragment)
        }

        var fragment = manager.findFragmentByTag(tag)
        if (fragment == null) {
            val className = destination.className
            fragment = instantiateFragment(context, manager, className, args)
            transaction.add(containerId, fragment, tag)
        } else {
            transaction.attach(fragment)
        }

        transaction.setPrimaryNavigationFragment(fragment)
        transaction.setReorderingAllowed(true)
        transaction.commit()

        return destination
    }
}
Run Code Online (Sandbox Code Playgroud)

对于第二个问题,我不知道如何修复它,实际上,我什至不明白片段是如何恢复其状态的(例如,当您旋转屏幕时),我绑定到用于fragment.setInitialSavedState(savedState)保存和恢复片段状态,但这在这种情况下无济于事。

实际上我需要知道的是何时重新创建片段视图

这是我的 GitHub 项目的链接,欢迎任何帮助。

Der*_*k K 0

仅当重新创建活动(例如屏幕旋转)时片段才会保存其状态,并且更改片段并不重要。来自文档:

在许多情况下,片段可能大部分被拆除(例如当放置在返回堆栈上且没有显示 UI 时),但直到其所属 Activity 实际需要保存其状态时,才会保存其状态。

来源

保存自定义状态:

将此方法放入片段中:

override fun onSaveInstanceState(outState: Bundle) {
    outState.putString("text", "some value")
    super.onSaveInstanceState(outState)
}
Run Code Online (Sandbox Code Playgroud)

并读取其中的值,例如onViewCreated

val text = savedInstanceState?.getString("text")
Run Code Online (Sandbox Code Playgroud)

屏幕旋转/手机语言更改或其他配置更改后 - 当活动(和片段)重新创建时,您将收到所需的值。