简体   繁体   中英

How can I correctly implement custom back navigation in a re-used, nestable fragment?

I've got a custom settings screen that recursively can create views based on config. The navigation of this mostly works fine. It's embedded in an Activity, Activity B .

To handle the recursive nature of the fragments, I update the values in a recycler view every time a next or previous fragment is navigated to. Again, this all works fine.

To get to the settings, I navigate from Activity A to Activity B using the navigation component.

Here is an image of Activity A, and the settingsFragment (really, activity B) in the navigation graph, if it helps clarify this setup:

在此处输入图像描述

Note the settingsFragment goes into itself.

I need the previous settings lists to load as I go back through the settings until the user reaches the top-level one. The problem I'm facing is, back navigation from the settings (SettingsFragment in Activity B), to Activity A is quite flakey. Initially, that is just when opening SettingsFragment, it works. But the further into nested settings menus you go, then an equal number of taps of the back button are required to get from the top SettingsFragment to ActivityA. So 3 levels down require 3 back button presses at the top settings level (totaling 5 or 6 taps up).

I think this is a problem to do with my custom back navigation code, which I need to change data in the ViewModel. But it's overwriting standard back navigation to Activity A. I thought I fixed this by trying to call requireActivity().onBackPressed() at the appropriate time. So that's where I'm at now.

Here's the relevant code:

val callback: OnBackPressedCallback =
                object : OnBackPressedCallback(true) {
                    override fun handleOnBackPressed() {
                        viewModel.onBackPressed()

                        if (viewModel.currentMenuId == null) {
                            isEnabled = false // Have to set this to false otherwise onBackPressed below begins an infinite loop.
                            requireActivity().onBackPressed()
                        }
                    }
                }

            requireActivity().onBackPressedDispatcher.addCallback(
                viewLifecycleOwner,
                callback
            )

I guess I don't understand how this should work if I'm re-using a fragment. Should I have a callback for each instance? And if so, how do I disable it at the top, correctly?

What happens when you don't add nested fragments to backstack. In that case onback press should take you directly to last fragment which was added to back stack.

I have created a similar kind of Component called StackFragment . Where in onBackPressed() is handled individually for fragments using childFragmentManger.

Hope this might help you to get some idea on your implementation.

堆栈片段

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM