popUpTo nested navigation graph ID not popping to startDestination - android

I'm trying to use popUpTo as part of configuring an action in androidx navigation to make sure the back button on the next screens returns to the specified fragment ID.
The problem is the fragment I want to navigate back to is defined as the startDestination of a nested graph. I would expect to be able to specify the ID of the nested graph in popUpTo, so that I don't have to link directly to a child fragment's ID, which I understand to be bad practice, if even not an error.
However, the only way to get the behavior I desire is by setting popUpTo to the ID defined as startDestination in the nested graph. Specifying the nested graph ID instead jumps over the fragments defined therein.
I could not find specific guidance on how to use popUpTo with nested graphs. Could anyone provide more details?

I would expect to be able to specify the ID of the nested graph in popUpTo, so that I don't have to link directly to a child fragment's ID, which I understand to be bad practice, if even not an error.
This should work correctly. If this does not work, it means something else is going wrong.
In my case, it turned out that elsewhere in the codebase the backQueue of NavController was manipulated manually (.clear()) was called.
After removing the offending code, I could update my popUpTo to refer to the nested graph ID, and the backstack got cleared as expected.

Related

Navigation graph start destination issue

I am using Navigation Graph in an activity as it is the recommended approach to be used for fragments.
I only want to load fragment based on given condition otherwise do not load i.e., keep the startDestination as null.
Is it possible to do so? I don't want conditional start destination.

How to use navigation component with a parent fragment?

I have an app, which is a single-activity app. I use dagger2 for di, and an abstraction for navigation.
Let's see a navigation flow: auth - select-info (A, B) - menu. As you can see, there are three main destinations, and the second one contains two screens. I want to make "select-info" as a parent fragment for A and B, but the way navigation component works, I cannot implement that behavior.
I tried to google it, but something close to this issue is an approach to use fragmenManager to go to parentFragment and internally use navComponent, but this approach does not work in my case, because somehow I need to change a navGraph.
As an alternative I see using viewPager in "select-info".

How to reorganize messy android navigation graph?

So I use a single nav_graph.xml for the whole app. As the app grow it become messy jumble like shown below, and now it become so laggy to move around.
Is there any trick to untangle this thing without changing the code too much?
I also had this situation and it is normal , but you should refactor as it gets harder to make changes to that navigation graph or better understand your use cases and do it in the first place. Anyway the solution to that is you make a nested navigation graph for every feature of the app (if possible) , for example for profile option make a profile nested navigation graph now all fragment related to profile will go under that navigation graph and the navigation graph will become more manageable another advantage is that you can scope a viewmodel to the nested navigation graph, that means you can share data related to profile via that viewmodel.
As your navigation graph above how can you share data between those fragment , first you can use arguments but those are for limited data types , second you can have a viewmodel which is scoped to your single activity and and all your fragment share that data but that is also a really messy solution and huge impact on memory usage, since all memory used by activity viewmodel will remain consumed as long as the app is running.
So go will nested navigation graph, or if you want to have more activities you can also do that in that case other activities have their own navigation graphs.

Circular Reference with Nested Nav Graphs

I have a complex navigation structure, I go from one nav graph then based on some logic, decide which nav graph to go to there. However both the nav graphs share 3 other nav graphs. See image below
Currently I get a circular reference error if I try to include each nav graph in the A & B. I have also tried creating a global action, which leads to illegal argument exception since it doesn't exist on the nav graph.
Please help!!!
I also don't know how to solve this. The Navigation Component should allow the reuse of modular graphs by passing some sort of ID from the initiating graph.
The only workaround I could think of was to create a copy of the graphs that have different origins.
For example, "Graph1" would now have two versions, "Graph1_from_GraphA" and "Graph1_from_GraphB". So "GraphA" and "GraphB" would reference them respectively.
If the graphs are not that far way, there is also the solution of conditional navigation, as described in the official documentation (https://developer.android.com/guide/navigation/navigation-conditional), in which we can pop the BackStack in the NavController with a result in the SavedStateHandle and then in the previous fragment we can redirect to the desired destination.

MvvmCross ViewModels not destroyed on FragmentManager.PopBackstackImmediate()

I have built a Xamarin Android app that presents the user with a series of data entry forms, like a wizard. The wizard has a bottom navigation bar with previous and next buttons, and a menu button that when pressed displays a list of all forms in the wizard and allows the user to jump to any given form.
The desired functionality is to preserve the linear navigation, so that when the user jumps to the middle of the wizard, they can still use the previous and next buttons to page through the various forms in order. They should also be able to use the hardware back button to view the previous form in the wizard.
I suspect my implementation is not MvvmCross friendly because I'm seeing some bugs with it, specifically my viewmodels are not destroyed when I clear the fragment backstack (wizard hosted in an Activity, each form is a Fragment).
How should I implement this?
Have you tried using this overload of PopBackStackImmediate? This one will pop all of the fragments until the one you specify in the string (if inclusive flag is passed, then that fragment is also popped) so you spare iterating all over the fragment backstack.
Activity.SupportFragmentManager.PopBackStackImmediate("myViewTag", (int)PopBackStackFlags.Inclusive);
where "myViewTag" is the UniqueImmutableCacheTag of your View
There has to be something unconventional about my implementation, but with a deadline and little help from the community, what do you do to fix your hack, but to hack it more?
My solution was twofold:
1) instead of using FragmentManager.PopBackstackImmediate(), I implemented a while loop with the condition: activity.SupportFragmentManager.BackStackEntryCount > 0, calling Close(fragment.ViewModel) in the body. This should have fixed the bug, but it didn't.
2) The ViewModels I was requesting to Close were still not being disposed, so I had to resolve the current IMvxMultipleViewModelCache and call GetAndClear on it with the expected parameters. This forced my ViewModels to be disposed so they will be recreated on the next viewing of its Fragment.
This feels like a hack. Closing a ViewModel should dispose of it whether it's associated with a Fragment or Activity, but for some reason it wasn't. That's the key to this bug, but like I said, deadline, hack on hack.

Categories

Resources