Fragments are getting overlapped on back button
Asked Answered
T

4

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

Theine answered 27/2, 2014 at 12:28 Comment(1)
solution 1 in the following answer worked for me https://mcmap.net/q/710269/-handling-fragment-back-stack-with-navigation-drawerSolvent
S
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();   
}
Sphalerite answered 27/2, 2014 at 12:34 Comment(7)
i don't want FragmentB in stack.I want my transaction to directly go to FragmentA, from FragmentC using backpressTheine
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.Sphalerite
how to add fragmentC to back stack.Theine
See my edit for adding C and you have to remove fragmentTransaction.addToBackStack(null); when you are going from A to B.Sphalerite
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.Sphalerite
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 ATheine
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.Sphalerite
P
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.

Painting answered 27/2, 2014 at 12:52 Comment(4)
I am adding same like this but fragment C is over lapping with fragmentATheine
the fragment can't be overlaped if you use replace instead of add in fragment transaction.Painting
when i press back button then c fragment is overlapping with a fragment.Theine
acoording to above code..add this -callPerticularScreen(screenNumber,false,null,null);-to call your frag from b-a, then back press. here,hence the fragment b not added in the backstack so that a will comePainting
H
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

Heinz answered 22/4, 2014 at 10:55 Comment(0)
C
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)
Coprophagous answered 22/12, 2016 at 10:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.