2

I'm opening fragments containing list, over and over again, then, ultimately, I want to clear the fragment stack to open a new Fragment once I reach the end of those fragments containing a list.

I don't know if i'm being clear so here is what I'm doing currently:

private final BroadcastReceiver onReceiveLaunchIncident = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            // Select the correct item from the DrawerLayout
            selectItem(drawerList.indexOf("Patrol"));

        }
    };

Currently it goes this way when I enter my BroadcastReceiver

Fragment D ---> Fragment A ---> Fragment E

And I want it to go this way:

Fragment D ---> Fragment E

enter image description here

private void selectItem(final int position) {
    addToDrawerIfNotExist(position);

    if (mDrawerListChild.getCheckedItemPosition() == position) {
        Log.i(TAG, "Same position selected in drawer");
    }

    mDrawerListChild.setItemChecked(position, true);
    mDrawerLayout.closeDrawer(mDrawerLinear);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
            BackHandledFragment fragment = fragmentListString.get(fragmentList.get(position));

            ft.replace(R.id.content_frame, fragment, fragment.getTagText())
                    .commitAllowingStateLoss();
        }
    }, 300);
}
Jaythaking
  • 2,200
  • 4
  • 25
  • 67

2 Answers2

2

You are having this problem because of the way you have added the first fragment. If you think about the backstack as just a record of transactions instead of fragments themselves you can see why you are always left with fragment A. When you add fragment A I'm guessing you are not setting that very first transaction to be included in the backstack. If that is the case the first entry you have in the stack is the change from A to B which is being undone when you perform your pop code above. Your problem should be resolved by adding the very first entry to the backstack as well using the addToBackStack call during the transaction.

The code example below uses the transaction replace which would allow you to still not add fragment A to the back stack as suggested above. The replace call is not included in the back stack and thus will just replace fragment A with E while leaving the back stack empty.

EDIT

private void selectItem(final int position) {
    addToDrawerIfNotExist(position);

    if (mDrawerListChild.getCheckedItemPosition() == position) {
        Log.i(TAG, "Same position selected in drawer");
    }

    mDrawerListChild.setItemChecked(position, true);
    mDrawerLayout.closeDrawer(mDrawerLinear);

    FragmentTransaction ft =  getSupportFragmentManager().beginTransaction();
    BackHandledFragment fragment = fragmentListString.get(fragmentList.get(position));

    ft.replace(R.id.content_frame, fragment, fragment.getTagText()).commit();
}

EDIT 2: removed the fade animation because that was causing the flicker where you would see fragment A for a split second before the transition to fragment E.

Bobbake4
  • 24,509
  • 9
  • 59
  • 94
  • I would not be a correct behavior for my app to return to that fragment unless you reach the end of those Fragment's list... Is there a way to add Fragment E at the end of the backstack THEN clear the stack keeping the last fragment added ? – Jaythaking Jul 18 '16 at 17:12
  • What you can do is perform your popping as you have it and in the `selectItem(drawerList.indexOf("Patrol"));` call to change to fragment E make the transaction a replace and do not set that transaction to be added to the back stack. This should pop everything back to A and then replace A with E. – Bobbake4 Jul 18 '16 at 17:49
  • I'm not sure I follow you here, I added the selectItem() method I used in my question... – Jaythaking Jul 18 '16 at 18:14
  • You should not have to post delayed and should not commitAllowingStateLoss unless you are sure you want that. I've made a slight edit which should work as expected. – Bobbake4 Jul 18 '16 at 18:43
  • if I don't put commitAllowingStateLoss I get somehow a crash. This does not append often, but this avoid it to occurs... I also did postDelayed because of the hamburger animation who flickr otherwise...I'll try making a variant without the postDelayed and see if this works – Jaythaking Jul 18 '16 at 18:54
  • You will get the commit crash if the activity has already called onSaveInstanceState, this could happen because of the post delayed. This should not be possible, and you should use a regular commit, if you take out the delayed posting. – Bobbake4 Jul 19 '16 at 15:10
  • It happens throughout the entire app at different place, even at place without delayed post. Many post here on stack are about that issue and the only fix is putting commitAllowingStateLoss. Also, I stopped having this issue after adding this...Related link--> http://stackoverflow.com/questions/14177781/java-lang-illegalstateexception-can-not-perform-this-action-after-onsaveinstanc – Jaythaking Jul 19 '16 at 15:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117753/discussion-between-bobbake4-and-jaythaking). – Bobbake4 Jul 19 '16 at 20:25
  • It was the fade animation that was causing the flickr... Thanks for helping – Jaythaking Jul 19 '16 at 23:16
1

How about this:

private final BroadcastReceiver onReceiveLaunchIncident = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                getSupportFragmentManager().beginTransaction().remove(frag).commit(); 
            }
        }
        // Select the correct item from the DrawerLayout
        selectItem(drawerList.indexOf("Patrol"));
    }
};
romtsn
  • 11,704
  • 2
  • 31
  • 49