8

I have created 3 Fragments namely (FragmentA, FragmentB, FragmentC) and one MainActivity. There is a button in each fragment which replaces itself with next Fragment till FragmentC.

I am replacing FragmentA (with) FragmentB (then with) FragmentC.

Transaction from FragmentA to FragmentB uses below function

    @Override
    public void fragmentreplacewithbackstack(Fragment fragment, String tag) {

        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.contner,fragment , tag);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();   
//      fragmentManager.executePendingTransactions();

    }

Transaction from FragmentB to FragmentC uses below function

public void fragmentreplace(Fragment fragment,String tag){
        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.contner,fragment , tag);
        fragmentTransaction.commit();   

    }

problem is when i press back button from FragmentC, FragmentC and FragmentA overlap with each other.

As below screen

Mayank Saini
  • 3,017
  • 24
  • 25
rajahsekar
  • 916
  • 1
  • 11
  • 25
  • solution 1 in the following answer worked for me https://stackoverflow.com/a/32199862/8101551 – kp85 Jul 19 '19 at 07:10

4 Answers4

5

You need to add Fragment C to backstack as well if you wanna go to Fragment B on back press from here.

So call the below for Fragment C as well.

 fragmentTransaction.addToBackStack(null);

EDIT - Change this current method you are using to go from B to C,

public void fragmentreplace(Fragment fragment,String tag){
    FragmentManager fragmentManager=getSupportFragmentManager();
    FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.contner,fragment , tag);
    fragmentTransaction.addToBackStack(null); //this will add it to back stack
    fragmentTransaction.commit();   
}
Atul O Holic
  • 6,692
  • 4
  • 39
  • 74
  • 2
    i don't want FragmentB in stack.I want my transaction to directly go to FragmentA, from FragmentC using backpress – rajahsekar Feb 27 '14 at 12:39
  • Then do not add Fragment B to the back stack. Add C to back stack so that when you press back it will be removed from the back stack and you will be taken to A since B is not in picture now. – Atul O Holic Feb 27 '14 at 12:44
  • how to add fragmentC to back stack. – rajahsekar Feb 27 '14 at 12:48
  • See my edit for adding C and you have to remove fragmentTransaction.addToBackStack(null); when you are going from A to B. – Atul O Holic Feb 27 '14 at 12:50
  • Did you remove the line fragmentTransaction.addToBackStack(null); when you are going from A to B? Also, please post the code you are trying now. – Atul O Holic Feb 27 '14 at 12:57
  • if i use fragmentTransaction.addToBackStack(null); from Transaction B to C then B is stored in stack and when i press back button from C,B appears not A – rajahsekar Feb 27 '14 at 12:58
  • Fragment C will be added to back stack as per above. addToBackStack adds the happenning transaction to back stack and not the one it is called from. Hence, as per your above, fragment C will be added. So when you go from A to B *DONT* add it. Instead add when you go from B to C. – Atul O Holic Feb 27 '14 at 13:02
0

why don't you just make a fragment activity with a frame layout in which you can replace that frame with any fragment..

Screen extends FragmentActivity
{
protected void onCreate(Bundle b)
{
    super.onCreate(b);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.work);

            callPerticularScreen(screenNumber,false,null,null);
     }
public void callPerticularScreen(int screenNumber,boolean addToBackStack,String nameTag,Bundle b)
{
    switch(screenNumber)
    {
    case registrationScreen:
        callFragForMiddleScreen(registrationPageFrag,addToBackStack,nameTag);
        break;
    case dashboardScreen:
        callFragForMiddleScreen(dashboardFrag,addToBackStack,nameTag);
        break;
        default:
            break;
    }
}

}

now from any fragment screen you can call this function to replace your fragment with another..like..

private void callFragForMiddleScreen(Fragment frag,boolean addToBackStack,String nameTag)
{
    transFragMiddleScreen=getFragManager().beginTransaction();
    transFragMiddleScreen.replace(getMiddleFragId(),frag);
    if(addToBackStack)
    {
            transFragMiddleScreen.addToBackStack(nameTag);
    }
    transFragMiddleScreen.commit();
    //getFragManager().executePendingTransactions();
}

from your fragement just call

Frag1 extends Fragment
{

onActivityCreate()
{
middleScreen=(Screen) getActivity();

middleScreen.callPerticularScreen(1,true,"tag");
}
}

layout for fragment activity..

<RelativeLayout
    android:id="@+id/rl2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/rl" >

    <FrameLayout
        android:id="@+id/middle_screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
</RelativeLayout>

just don't add the fragment B to back stack so that you can come from c-> a directly.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
deepak tiwari
  • 107
  • 10
0

I had the same problem and this answer of Budius helped me a lot.

You can solve your issue in the following way:

1) Instantiate the following listener (you have to keep reference of the FragmentC's instance) and, since fragmentA is the only fragment added to the backstack, when the user presses the back button, the number of transactions in the backstack will be zero

private OnBackStackChangedListener backStackChangedListener = new OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        if(getSupportFragmentManager().getBackStackEntryCount()==0) {
            if(fragmentC!=null) {
                getSupportFragmentManager().beginTransaction().remove(fragmentC).commit();
            }
        }
    }
};

2) Add the listener in the MainActivity when the latter is started

getSupportFragmentManager().addOnBackStackChangedListener(backStackChangedListener);

3) Remove the listener when the activity is stopped

Community
  • 1
  • 1
bardi
  • 373
  • 5
  • 17
0

25 support library

for example if you have

A -> B -> C
A id is 0
B id is 1
C id is 2

to rollback to A fragment just call

getFragmentManager().popBackStackImmediate(0 /* ID */, 0 /* flag */);

0 - is ID of backstack entry to rollback

or

popBackStackImmediate(1, FragmentManager.POP_BACK_STACK_INCLUSIVE)

FragmentManager.POP_BACK_STACK_INCLUSIVE, it means you want also remove supplied ID

also you can call

getFragmentManager().popBackStackImmediate("stack_name", 0)

"stack_name" it's a name of backstack to revert

for example

A -> B -> C -> D
A in MAIN_BACK_STACK
B in MAIN_BACK_STACK
C in SEPARATE_BACK_STACK
D in SEPARATE_BACK_STACK

if you want to revert to fragment B just call

getFragmentManager().popBackStackImmediate("MAIN_BACK_STACK", 0)
or
getFragmentManager().popBackStackImmediate("SEPARATE_BACK_STACK", FragmentManager.POP_BACK_STACK_INCLUSIVE)
iscariot
  • 434
  • 7
  • 14