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

时间:2019-04-22 20:56:38

标签: android android-fragments android-architecture-components android-navigation android-bottomnav

当前,我正在使用带有底部导航栏的Android导航组件。在玩游戏时,我意识到了两个事实:

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

可以通过使用自定义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 } } 将重用已经存在的片段

fragment.setInitialSavedState(savedState)

问题

对于第二个问题,我不知道如何解决它,实际上,我什至不了解该片段如何恢复其状态(例如,当您旋转屏幕时),我不得不使用{{1} }保存和恢复片段状态,但这在这种情况下无济于事。

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

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

2 个答案:

答案 0 :(得分:1)

检查此博客http://www.androiddevelopment.co.in/2019/05/how-to-save-android-activity-state.html,此博客介绍了在活动被破坏时如何保存活动状态。

例如,如果您在活动运行时更改手机的语言(因此需要加载与项目不同的资源)。另一个非常常见的情况是将手机旋转到侧面,以便重新创建活动并将其显示在横向中。您可以使用此技术存储应用程序的实例值(选择,未保存的文本等)。

答案 1 :(得分:0)

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

  

在很多情况下,片段可能大部分都被撕裂(例如,当放置在没有显示UI的后堆栈上),但是直到其拥有的活动真正需要保存其状态时,它的状态才会被保存。

Source

保存自定义状态:

将此方法放在片段中:

override fun onSaveInstanceState(outState: Bundle) {
    outState.putString("text", "some value")
    super.onSaveInstanceState(outState)
}

例如在onViewCreated内读取值:

val text = savedInstanceState?.getString("text")

在屏幕旋转/电话语言更改或其他配置更改之后-重新创建活动(和片段)时,您将获得所需的值。