Android导航组件saveState和restoreState

Ant*_*nov 7 android kotlin

伙计们,我需要你们的帮助。

我使用 android 导航组件,想要在用户按下按钮后保存 backstack 并在之后恢复它。我找到了2个方法

navController.saveState(): BundlenavController.restoreState(bundle: Bundle)

但我在使用它时遇到问题。看起来 saveState 工作得很好(我看到了包和里面的 backstack),但我不明白如何使用 RestoreState,因为文档说:

从包中恢复所有导航控制器状态。这应该在调用 setGraph 之前调用。

https://developer.android.com/reference/kotlin/androidx/navigation/NavController#restorestate

好吧,我做到了,似乎后退堆栈已恢复,但在屏幕上我看到第一个片段(而不是我保存时的片段)。我做错了什么?

代码:

第一个片段

    private val TAG = this::class.java.name

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        btn_forward.setOnClickListener { findNavController().navigate(R.id.action_firstFragment_to_secondFragment) }
        btn_back.setOnClickListener { requireActivity().onBackPressed() }
    }

}

Run Code Online (Sandbox Code Playgroud)

第二个片段

class SecondFragment : Fragment() {
    private val TAG = this::class.java.name

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        btn_forward.setOnClickListener { findNavController().navigate(R.id.action_secondFragment_to_thirdFragment) }
        btn_back.setOnClickListener { requireActivity().onBackPressed() }
    }

}
Run Code Online (Sandbox Code Playgroud)

第三片段

class ThirdFragment : Fragment() {
    private val TAG = this::class.java.name

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_third, container, false)
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        btn_finish.setOnClickListener {
            (requireActivity() as MainActivity).saveState() //here save bundle
            requireActivity().finishAfterTransition()
        }
        btn_back.setOnClickListener { requireActivity().onBackPressed() }
    }

}
Run Code Online (Sandbox Code Playgroud)

主要活动

class MainActivity : AppCompatActivity() {
    private val TAG = "MySuperActivity"

    lateinit var navController: NavController
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(TAG, "onCreate($savedInstanceState) called")

        initNavController()
    }

    private fun initNavController() {
        val navHostFragment = nav_host_fragment as NavHostFragment
        val graphInflater = navHostFragment.navController.navInflater

        val graph = graphInflater.inflate(R.navigation.main_graph)

        navController = navHostFragment.navController
        navHostFragment.childFragmentManager
        if (App.instance.savedBundle != null) {
            Log.d(TAG, "bundle: ${App.instance.savedBundle}")
            navController.restoreState(App.instance.savedBundle)
            graph.startDestination = R.id.thirdFragment
        }

        navController.graph = graph
        Log.d(TAG, "navController.currentDestination: ${navController.currentDestination}")
        Log.d(TAG, "navController.graph.startDestination: ${navController.graph.startDestination}")
    }

    fun saveState(){
        App.instance.savedBundle = navController.saveState()
        Log.d(TAG, "saveState() : ${App.instance.savedBundle}")
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一些日志:日志

完整代码:github

小智 0

我不确定我的答案是否对您有帮助,但我在尝试从处理旋转中保存导航状态时遇到了很多问题。我遇到的问题来自旧版本的导航组件,我更新到最新版本,它解决了问题:

def android_navigation = '2.3.4'
implementation "android.arch.navigation:navigation-fragment-ktx:$android_navigation"
implementation "android.arch.navigation:navigation-ui-ktx:$android_navigation"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$android_navigation"
Run Code Online (Sandbox Code Playgroud)