How to avoid fragment recreation using navigation architecture component? - android

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!

Related

Excluding certain destinations from navigation backstack?

Is there some way I can prevent certain destinations in my navgraph from being added to the backstack?
For example, lets say I have 5 fragment destinations: A, B, C, D and E.
navgraph looks like this: A -> B -> C -> D -> E -> A (its a loop)
Now B, C, D and E are fragments that I dont want the user to be able to navigate back to. If the user navigates back at any point in the navgraph, I want them to go to the previous A fragment.
I'm currently doing this by overriding onBackPressed with complicated logic that keeps popping the back stack until a fragment A is reached.. It works but it feels far from optimal. If I could simply prevent B, C, D and E fragments from being added to the backstack it would be much simpler.
SOLUTION 1:
The app:popUpTo and app:popUpToInclusive are exactly what you may be looking for
Via the documentation,the xml attributes will
Pop up to a given destination before navigating. This pops all non-matching destinations from the back stack until this destination is found
Let me explain this to you with three fragments A , B, C
A (start) -> B -> C
if I want to navigate to C
and pop all including A(startscreen) then the code will be:
<action
android:id="#+id/B_to_C"
app:destination="#id/C"
app:popUpTo="#+id/A"
app:popUpToInclusive="true" />
if I want to navigate to C and pop all excluding A then the code will be:
<action
android:id="#+id/action_B_to_C"
app:destination="#id/C"
app:popUpTo="#+id/A"/>
SOLUTION 2:
Using the popBackStack method of the NavController class which does the same job as the onBackPressed but in an elegant way
If you have three fragments : A, B, C
And you are currently in fragment C and would like to go back to A before navigating anywhere(or not navigating anywhere if you please)
NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentB, true);
OR
NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentA, false);
where true or false will indicate if you actually want the destination to stay(false) or be popped off the stack too (true)

clear back stack except last two activities

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.

Android - Pop two or more fragments but don't the top

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.

Android start a new activity before another activity in backstack and clear activities above old activity

I'm stuck with an Activity backstack question. Let's say I have 5 activities in my backstack: like Activity A, Activity B, Activity C, Activity D and Activity E. At some point I want the user to go to another Activity G, when pressed on the back button on Activity E. Activity G needs to be put after Activity B, so I want Activity C and Activity D removed from the backstack (otherwise the user would go to Activity D).
Current situation A --> B --> C --> D --> E
Preferred situation A --> B --> G
Now I understand I can use FLAG_ACTIVITY_CLEAR_TOP when Activity G would have been in the backstack. But the Activity isn't. Also I don't want to use FLAG_ACTIVITY_NEW_TASK because then Activities A and B would also be gone.
Another approach would be to put
android:noHistory="true"
within the manifest for Activities C and D, but this would make the user go back to Activity B every time the user pressed the back button from within Activity C or D.
Who can point me in the right direction?
You can try below
C ----startActivityForResult----------> D ---startActivityForResult--> E
handle onActivityResult with result accordingly to finish Activities, make sure its chained action calls
When you start activity from C->D you put finish();
Intent intent=new Intent(C.this,D.class);
startActivity(intent);
finish();
same way for D->G this way it is possible.

Fragment not being removed from back stack

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.

Categories

Resources