Clear Android Fragment back stack without popping?
Asked Answered
A

2

9

We have an Activity that contains a SlidingMenu (https://github.com/jfeinstein10/SlidingMenu) in which there's three options, let's call them A, B1, C1. These correspond to Fragments that we show in the Activity. When you select a different option from the SlidingMenu I replace the current fragment with the new one via the FragmentManager.

From Fragment B1 you can go to two others, let's call them B2 and B3. Here we want the Back key to take you from B2 -> B1 or from B3 -> B1, so I call transaction.addToBackStack(null). If we select an option from the SlidingMenu when you're on B2 or B3 we want to clear the back stack, so I use code as suggested in this question Clear back stack using fragments which calls popBackStack() until it's clear.

So far so good.

From Fragment C1 you can go to Fragment C2. As C1/C2 are more of a Master/Detail design I use

fragmentTransaction.setCustomAnimations(R.animator.slide_in_from_right,
    R.animator.slide_out_to_left, R.animator.slide_in_from_left,
    R.animator.slide_out_to_right);

to add a slide animation where C1 slides out to the left as C2 slides in from the right, and vice versa. Pressing the Back key while on C2 takes us back to C1, with the reverse animation, and all is good.

BUT

If you select A or B1 from the SlidingMenu and we popBackStack() to get rid of C1 from the back stack, then it slides C2 out to the right, which looks weird. What I'd like to do is clear the back stack without running the animation, but I can't find a way to do that. I've tried calling popBackStackImmediate() instead, but that doesn't seem to make any difference.

As an alternative I guess I could avoid calling addToBackStack at all, and instead manually handle the user pressing the Back key via Activity.onBackPressed(), but perhaps there's a solution I just can't see?

Aun answered 26/4, 2013 at 12:8 Comment(0)
B
6

You could try the follow, though I am unfamiliar with .remove() it seems that it should do what you want:

myFragmentClass myFragC1 = (myFragmentClass) getFragmentManager().findFragmentByTag("theTagYouUsedWhenAddingToBackStack");
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(myFragC1);
transaction.commit();
Banta answered 26/4, 2013 at 12:21 Comment(5)
That seems to do exactly what I need. Thanks!Aun
@JonathanCaryl Great! I'm glad it worked as I was not actually 100% sure it would :)Banta
@YaroslavMytkalyk With support lib its getSupportFragmentManager() ?Marashio
@DerekBeattie yes, that's what I've used. When I remove the Fragment, and then add a new one, pressing back still leads to previous one.Mclean
But I guess there is one problem wit this, the stack count won't be updated.Photoluminescence
A
4

Sadly, I don't know how to make it correctly so here is my solution (actually I've quite modified other stackoverflow answer)

In base fragment class which is extended by all other fragments):

public static boolean sDisableExitAnimation = false;

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (sDisableExitAnimation && !enter) {
        return AnimationUtils.loadAnimation(getActivity(), R.anim.clear_stack_exit);
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}

To clear stack you need to call:

ScreenFragment.sDisableExitAnimation = true;
manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

And finally clear_stack_exit animation itself (I didn't find a way to get it from FragmentManager itself):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="220"
        />

    <scale
        android:fromXScale="1"
        android:toXScale="0.975"
        android:fromYScale="1"
        android:toYScale="0.975"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="220"
        />

</set>

This way you'll have correct clear stack animation. Just dodn't forget to clear sDisableExitAnimation variable before starting next transition.

Abaft answered 2/8, 2013 at 10:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.