Handle Fragment Backstack According to the Current Fragment

Viewed 234

Problem 1

I have a Navigation Drawer and most of my fragment transactions happens from here. So say I have 4 Items in my drawer and I am doing the transaction from all of them. So if I am at the fragment [A] and now I click on the fragment [B], I need to come back to the previous fragment i.e. [A]. But if I keep clicking on the Item B of the navigation drawer that opens the fragment [B], I keep adding it to the backstack and when I press the back button, I am still at the same fragment.

Problem 2

How do I achieve the Clear Top behavior that is used for the intents for the fragments. As intents have the power to clear the activities from the stack from the top only, I want to achieve the same behavior.

1 Answers

Problem 1 & 2 solution Idea:

Create an Interface say FragmentInstanceHandler

public interface FragmentInstanceHandler {
   public void openFragment(Fragment fragment, String fragmentTag);
}

Create a BaseFragment like below and extend this to all your Fragment classes:

public BaseFragment extends Fragment {
   public FragmentInstanceHandler fragmentInstanceHandler;
   public void setFragmentInstanceHandler(FragmentInstanceHandler fragmentInstanceHandler) {
       this.fragmentInstanceHandler = fragmentInstanceHandler;
   }
}

Implement the FragmentInstanceHandler interface to the Activity in which you are going to open all the Fragments. Let's say Activity is MainActivity:

public MainActivity extends Activity implements FragmentInstanceHandler {
  private BaseFragment currentFragment;
  @Override
  public void openFragment(BaseFragment fragment, String fragmentTag) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment oldFragmentInstance = fragmentManager .findFragmentByTag(fragmentTag);
        boolean fragmentPopped = fragmentManager.popBackStackImmediate (fragmentTag, 0);
   if (!fragmentPopped && oldFragmentInstance == null) {
        fragment.setFragmentInstanceHandler(this);       
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.container, fragment, fragmentTag);
        fragmentTransaction.addToBackStack(fragmentTag);
        fragmentTransaction.commit();
        currentFragment = fragment;
    } else if(fragmentPopped ){
        currentFragment = oldFragmentInstance;
     }
     if(mDrawerLayout!= null)
           mDrawerLayout.closeDrawers();
 }

}

Now whenever you want to open a new Fragment even from any other Fragment you can call method like below, It is advised to provide new tag if you want to have new instance of same Fragment:

fragmentInstanceHandler.openFragment(new MyFragment(), "FragmentNewInstance");

You can tweak FragmentInstanceHandlerto add your own method to replace the current Fragment instead of adding. Above solution just gives you an idea how you can acheive your solution by putting and mananging all your code from one place.

Related