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).
Related
I'm working with the fragments navigation and have a problem removing one from the back stack. Here're specifics:
I have 3 independent fragments (let's name them A1, A2, and A3) and each of them can navigate to fragment B using findNavController().navigate(), which after some actions navigates to fragment C using the same method.
What I need is when the back arrow is pressed I return to the A-fragment(which I started from) avoiding fragment B.
I've tried using app:popUpTo, and popBackStack but it hadn't worked. Also, I'm highly not recommended to use FragmentManager
You can use
findNavController().popUp(2)
Fox example, I have activities A, B, C. Each of these activities is a container for fragments F1, F2, F3. Also, I have another fragment - F4. This fragment which can be opened from fragments F1, F2, F3. In addition, from fragment F4 I need to perform navigation to activities A B and C and also remove from back stack fragment F4. Now I close the F4 fragment for this and using the fragment result API I pass the result to the previous fragment, and from the previous fragment I perform the navigation to the activity I need.
But in this case, the previous fragment appears on the screen for a few seconds, but I would like it to look like I navigated from fragment F4.
Is it possible to avoid this behavior ?
Please, help me ?
We have multiple screens in our app and to switch between them we use FragmentTransactions, primarily replace, and we add fragments to the backstack when we do so. While doing so we stay within the same MainActivity.
So if we transition from Fragment A to Fragment B via some button we now have a stack that looks like
B
A
If we go to another Fragment C it goes on top of the stack like so
C
B
A
However, sometimes we transition to a fragment D, such that we want to wipe out the backstack so that users can no longer navigate back through C, B, A. We now want our backstack after navigating to D to look like this.
D
But in order to do so we need to clear the backstack using:
FragmentManager supportFragmentManager = getActivity().getSupportFragmentManager();
while(supportFragmentManager.getBackStackEntryCount() > 0)
{
supportFragmentManager.popBackStackImmediate();
}
clearingBackStack = false;
But when we do so, the onResume of fragments C,B and A are called. This is not the functionality we intend and can have negative consequences such as making unnecessary server calls. We have also noticed on low end devices that we see a flash of the popped fragments as they come off the stack.
We wish to avoid this behavior, is there a way to pop the entire fragment backstack without the popped fragments being activated in anyway?
I have a small layout in my activity that I add Fragments to based on the User navigating through the app.
Assuming the user navigates thusly:
Activity -> Fragment A -> Fragment B -> Fragment C -> Button Click
I would like to be able to to hide the Fragments and show the blank Activity again.
This is how I'm adding the Fragments to the activity:
protected void addFragment(Fragment fragment)
{
getSupportFragmentManager().beginTransaction().replace(R.id.secondary_fragment, fragment).addToBackStack(fragment.getTitle()).commit();
}
To clear all the Fragments, I use:
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
However, is there a way to clear the fragments in a way that if the user presses back, they would be able to go back to Fragment C (as opposed to exiting the App)?
Maybe instead of pop all the backStack, you just get the fragment view by id and setVisibility to invisible?
Try starting a new instance of your Activity with a clear stack on the button press (if I'm correct in assuming this comes after C as you described). This way the First Activity instance will still have up to Fragment C and the Second Activity instance will be whatever you like (Fragment A > Fragment D > Fragment F). And you won't need to pop/clear any back stack for any Activity.
HTHs
My Activity backstack structure looks like this:
A(Landing page) -> B(List screen) -> C(Details screen)
|----> D(Post
item screen) -> E(Post result screen)
Both B & D are direct child of A.
I wanted to provide a way for user to view the detail(C) from the result screen(E). While they go away, I wanted to remove D & E so that they can't go back when pressing back. Once jumped when user press back from C then they should go back to A instead.
EDIT: However, user can press back on E screen to go back and make change in D screen to fix whatever mistake they made so I kinda have to keep D in backstack as well.
What is the best way of doing this? Should I prevent D&E from ever going into backstack and handle my own navigation? Is there a way to clear D & E specifically and keep everything else? Or is there a better way to do this?
I considered using Clear Top flag but if user never visits C before Clear top wouldn't work as you can't go back to A afterward.
I use Activity.finish() to hide a Activity from the backstack.
As an example:
The user sees activity B and starts activity C. After stating of C call finish to hide B from the backstack:
startActivity(<Activity-C intent>);
finish();