0

I have fragment A,B,C,D,E and navigation flow is A->B->C->D->E . So you can say that A is a base fragment from where navigation is starting.

Naviagation flow

Add fragment with Backstack          Navigate to Fragment A         
A                                      E  
  -> B (Add B to backstack)                -> D (Remove E from backstack)  
B                                      D 
  -> C (Add C to backstack)                -> C (Remove D from backstack)  
C                                      C 
  -> D (Add D to backstack)                -> B (Remove C from backstack)
D                                      B 
  -> E (Add E to backstack)                -> A (Remove B from backstack)

                                      ** Trying to back from A and message pops

                                      (Press once again to exit!)

Add fragment with backstack

public void pushFragmentWithBackState(Fragment DestinationFragment) throws Exception {
        try {
            Fragment SourceFragment = this;
            int viewResourceID = ((ViewGroup) SourceFragment.getView().getParent()).getId();
            FragmentManager fragmentManager = getFragmentManager();

            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);
            ft.add(viewResourceID, DestinationFragment);
            ft.hide(SourceFragment);
            ft.addToBackStack(DestinationFragment.getClass().getName());
            ft.commit();
        } catch (Exception ex) {
            throw ex;
        }

    }

Back to Fragment A (check Navigate to Fragment A)

In this code I am checking that if there is no back stack entry in fragment manager that mean it we are on Fragment A and I am display message Press again to Exit or simply back from fragment.

 @Override
    public void onBackPressed() {
        // code here to show dialog
        //super.onBackPressed();  // optional depending on your needs
        if (getSupportFragmentManager().getBackStackEntryCount() >= 1) {
            BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
            if (fragment != null) {

                if (!fragment.onFragmentBackPressed()) {
                    //super.onBackPressed();
                    if (back_pressed + 2000 > System.currentTimeMillis()) {
                        finish();
                    } else {
                        Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
                        back_pressed = System.currentTimeMillis();
                    }
                }
            } else {
                //super.onBackPressed();
                if (back_pressed + 2000 > System.currentTimeMillis()) {
                    finish();
                } else {
                    Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
                    back_pressed = System.currentTimeMillis();
                }

            }
        } else {
            if (back_pressed + 2000 > System.currentTimeMillis()) {
                finish();
            } else {
                Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
                back_pressed = System.currentTimeMillis();
            }
        }
    }

ISSUE

My issue is started if I am trying to navigate from E -> B and remove all stack exclusively

From Fragment E

 poptoBackStackFragment(B.class);

Method

public boolean poptoBackStackFragment(Class SourceFragmentClass) {
        getFragmentManager().popBackStack(SourceFragmentClass.getName(),0);
        return true;
    }

When I am trying to do this it will not clear fragment list(getSupportFragmentManager().getFragments()) from fragment manager and with wrong position and when again push in flow for ex. B->C->D fragment list is like :

Find this in Back to fragment A

 BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1); 

Example :

  • fragment list 1 position having B fragment
  • fragment list 4 position having C fragment
  • fragment list 3 position having D fragment
  • fragment list size is also 5 instead of 2
  • there is no sequence in adding fragment in list .Normally it should be position 0,1,2 but instead it is 1,4,3

And because of that my logic of check whether I am on a base fragment is failed and message is coming even I am not on starting fragment (Press again to exit).

Why fragment list is not clear when I am navigate to B and remove all fragment to stack? Am I missing something ? Please help.

Note : I also used FragmentManager.POP_BACK_STACK_INCLUSIVE for clear it from stack but same issue occured.

KDeogharkar
  • 10,939
  • 7
  • 51
  • 95

1 Answers1

0

There is no method getFragments on FragmentManager, or rather there is, but it is hidden and not supposed to be used. It isn't specified how it's supposed to behave anywhere. I think you should use getBackStackEntryAt instead, it should have well-specified behavior.

Malcolm
  • 41,014
  • 11
  • 68
  • 91