I've noticed a strange behaviour when not adding a framgent transaction to the back stack. I have 4 fragments: A, B, C and D. The transaction for the C fragment isn't added to the back stack. First I add A, then B, then C. Then I press BACK. A is displayed, which is normal. Then I add D and I press BACK. The result is that the fragment C is displayed. Is there something I am missing, because I would expect C to be out of the back stack and to see fragment A.
The transaction for the C fragment isn't added to the back stack.
ok.
First I add A, then B, then C. Then I press BACK. A is displayed,
If you have added B to the backstack, it should display B and not A.
Then I add D and I press BACK.
If you have not added C, then it should show B and not C. If it is showing C that means that you have added C to the backstack.
Is there something I am missing.
From my understanding of the situation, you have not added B to the backstack and you have added C to the backstack.
Related
In my app I have one Activity and the rest are fragments. Right now I am trying to get run as follows. Let's say, I have Fragments A (Home), B, and C. The scenario is this:
I navigate from A to B that shows me some data that I pass from A by Safe args. Then I navigate from B to C to edit data shown in B. Then I go back from C to B and B shows me the edited data in C. Lastly, I go back to home. That's all.
I pass data by Safe args, but the problem is, when I come back to B from C, I cannot navigate back to A because the navigateUp() brings me back to C instead of going to A.
Navigating methods:
From A to B: Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navController().navigate(HomeFragmentDirections.actionNavHomeToNavB(some_string_data))
From B to C: Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navController().navigate(BFragmentDirections.actionNavBToNavC(string_data_in_B))
From C to B: Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navController().navigate(CFragmentDirections.actionNavCToNavB(edited_string_data_from_B))
From B to A: Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navController().navigateUp()
I also tried to use navigateUp() before going back to B, which throws exception that the destination does not exist and also, I tried to use popBackStack() to take the C from stack out so that the navigateUp() in B can bring me back to Home. No success yet.
I have 4 fragments in a drawer, lets call them fragment A, B, C, D. I use navigation architecture to bind my fragments with the drawer.
Fragment A is my entry point and from there I can navigate anywhere on the drawer.
Suppose I take the path A > B > C > B > C
If I press back from C, it goes to B then to C again and then to B and finally to A, but I don't want that.
When I press the back button from C, I want it to just go back to B then A without recreating fragments that are already in the back stack. Can someone please help on how to achieve this ?
When I press the back button from C, I want it to just go back to B
then A without recreating fragments that are already in the back
stack.
When you are navigating to a destination, you can pop the old instance of the destination from the back stack. Just add the pop inclusive to all your action in nav graph.
<!-- Add this in the actions navigating to B -->
app:popUpTo="#id/B"
app:popUpToInclusive="true"
Explanation
What the above pop behavior will do is, when you are navigating from, say C > B, it will pop everything till B (inclusive) from the back stack and add the latest instance of B on the back stack.
A > B > C > B > C will have a back stack:
A
A, B
A, B, C
A, B
A, B, C
Note:
The inherent assumption here is that this is not a valid case in your example.
A > B > C > D > B > C leads to a back tracking of C > B > D > A. Please be aware that in the above solution when you navigate to second B, it will pop out D from you back stack too!
For Activity A, B, C and D I have a flow like A->B->C->D. When I'm going to start D from C I need to clear A and B from back stack.
I have the following scenario:
A(Bottom) -> B -> C -> D(Top) -back-> A
A(Bottom) -> B -> C -back-> B -back-> A
Once I'm on the top (D fragment) I want to pop B and C fragment. On this way when I press back from D I can to A.
I want to avoid the transitions on B and C when I back from D.
A(Bottom) -> B -> C -> D(Top) -back-> C -back-> B -back-> A
It is even posible?
If I understand your situation correctly, then when creating fragment D right before that you can try getFragmentManager().popBackStack() which will look at your fragment stack and simply pop the last fragment. For this to work, you need to ensure that B and C are on the backstack so when creating those fragments you will need to call addToBackStack(null). Now, when creating fragment D you can just popBackStack() twice and that will bring you back to A. I hope I am understanding your situation correctly.
I need to create a specific behavior at some point in my app. I use a navigation drawer and I replace fragments in a frame layout.
Let's say I have some fragments in the backstack: A -> B -> C.
A is one of the root fragments in my app, if the back button is pressed on A, the app quits.
When I am on C (with A and B in the backstack) I want to go to E with D in the backstack. Meaning if I press the back button on E, I want to go to D (D being another root fragment in my app, if I press the back button on D the app quits).
For now I clear the back stack, then I replace the current fragment with D and then with E.
The problem with this is that I see the fragment A for a small amount of time during the transition from C to E. (And it's ugly right?)
To avoid showing D during the transition from C to E, you can add a boolean which keeps track of whether it's the first time D was active. You check it in D's onActivityCreated; if it's the first time D was active (when you really want to show E), don't load the content, then flip the boolean, so that you know to load the content next time D is active.
The first part you can do (C -> E with D on backstack). Simply add both to the same transaction:
getFragmentManager().beginTransaction()
.add(R.id.container, FragmentD.newInstance())
.add(R.id.container, FragmentE.newInstance())
.addToBackStack(null)
.commit();
And then you will transition smoothly to E without seeing D, but D will be on the backstack beneath E.
Unfortunately there is no way to remove items from the backstack other than popping them from the stack (you can't remove something from the bottom of the stack).