0

I have a main activity which hosts multiple fragments. I have a base fragment class which is inherited by all other fragments.

I have a main home screen fragment which have some buttons to display sub fragments. Now inside the sub fragment i have some buttons which displays its sub fragments. Now when i click back button i should go back to the previous fragment from which i have opened the current fragment but its always taking me to home screen fragment.

This is how i have written the main activity code

public class MainActivity extends AppCompatActivity implements 
FragmentDrawer.FragmentDrawerListener, View.OnClickListener {


private Context context;
public HashMap<String, Stack<BaseFragment>> mStacks;

private static String TAG = MainActivity.class.getSimpleName();

private Toolbar mToolbar;
private FragmentDrawer drawerFragment;

private TextView toolbarTitle,toolbar_signout;
public String mCurrentTab;

private ActionBar actionBar;
public BaseFragment fragment = null;
public String title;

private DrawerLayout drawer_layout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    context = this;

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);
    actionBar = getSupportActionBar();

    actionBar.setDisplayShowHomeEnabled(true);
    actionBar.setDisplayShowTitleEnabled(false);

    toolbarTitle = (TextView) findViewById(R.id.toolbar_title);
    toolbar_signout = (TextView) findViewById(R.id.toolbar_signout);
    toolbar_signout.setOnClickListener(this);
  //  toolbarSettings = (ImageView) findViewById(R.id.toolbar_settings);

    mStacks = new HashMap<String, Stack<BaseFragment>>();
    mStacks.put(MyConstants.TAB_HOME, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_INCIDENTS, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_LICENSE, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_SCHEDULE, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_CREATE, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_SCHEDULE_DETAILS, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_CHECKLIST_WAREHOUSE, new Stack<BaseFragment>());
    mStacks.put(MyConstants.TAB_UPLOAD_FILES, new Stack<BaseFragment>());

    drawerFragment = (FragmentDrawer)
            getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
    drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
    drawerFragment.setDrawerListener(this);

enter code here
    displayView(0);
}


@Override
public void onDrawerItemSelected(View view, int position) {
    displayView(position);
}

private void displayView(int position) {

    title = getString(R.string.app_name);
    switch (position) {
        case 0:
            mCurrentTab = MyConstants.TAB_HOME;
            mStacks.get(mCurrentTab).clear();
            fragment = new HomeFragment();
            pushFragments(mCurrentTab, fragment, false, true);
            title = getString(R.string.Incidents);
            break;
        case 1:
            mCurrentTab = MyConstants.TAB_INCIDENTS;
            mStacks.get(mCurrentTab).clear();
            fragment = new IncidentFragment();
            pushFragments(mCurrentTab, fragment, false, true);
            title = getString(R.string.Incidents);
            break;

        case 2:
            mCurrentTab = MyConstants.TAB_LICENSE;
            mStacks.get(mCurrentTab).clear();
            fragment = new LicensesFragment();
            pushFragments(mCurrentTab, fragment, false, true);
            title = getString(R.string.Licences);
            break;
        case 3:
            mCurrentTab = MyConstants.TAB_SCHEDULE;
            mStacks.get(mCurrentTab).clear();
            fragment = new ScheduleFragment();
            pushFragments(mCurrentTab, fragment, false, true);
            title = getString(R.string.ScheduleVisits);
            break;
        case 4:
            mCurrentTab = MyConstants.TAB_CREATE;
            mStacks.get(mCurrentTab).clear();
            fragment = new CreateScheduleFragment();
            pushFragments(mCurrentTab, fragment, false, true);
            title = getString(R.string.SchedulenewVisits);
            break;
        default:
            break;
    }


}


public void pushFragments(String tag, BaseFragment fragment, boolean shouldAnimate, boolean shouldAdd) {
    if (shouldAdd)
        mStacks.get(tag).push(fragment);
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    /*
     * if(shouldAnimate) ft.setCustomAnimations(R.anim.slide_in_right,
     * R.anim.slide_out_left);
     */
    ft.replace(R.id.container_body, fragment);

    ft.commit();

}

@Override
public void onBackPressed() {
    boolean temp = true;
    if (temp) {
        temp = false;

        if (mStacks.get(mCurrentTab).size() == 1) {
            if (mCurrentTab.equals(MyConstants.TAB_HOME)) {
            } else {
                displayView(0);
            }

        } else {
            int stackSize = mStacks.get(mCurrentTab).size();
            BaseFragment fragment = mStacks.get(mCurrentTab).get(stackSize - 1);
            //popFragments();
            if (fragment.onBackPressed())
                popFragments();
        }
    } else {
        // do nothing.. fragment already handled back button press.
    }
    temp = true;
}



public void popFragments() {
    /*
     * Select the second last fragment in current tab's stack.. which will
     * be shown after the fragment transaction given below
     */
    Fragment fragment = mStacks.get(mCurrentTab).elementAt(
            mStacks.get(mCurrentTab).size() - 1);

    /* pop current fragment from stack.. */
    mStacks.get(mCurrentTab).pop();
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    // ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
    ft.replace(R.id.container_body, fragment);
    ft.commit();
}
}

Now in my home screen button clicks i am calling the fragments in this way

 layout_schedule.setOnClickListener(new View.OnClickListener() {
                                           @Override
                                           public void onClick(View view) {
                                               mActivity.mCurrentTab = MyConstants.TAB_SCHEDULE;
                                               mActivity.mStacks.get(mActivity.mCurrentTab).clear();
                                               mActivity.fragment = new ScheduleFragment();
                                               mActivity.pushFragments(mActivity.mCurrentTab, mActivity.fragment, false, true);
                                               mActivity.title = getString(R.string.ScheduleVisits);
                                           }
                                       }
    );

    layout_newincident.setOnClickListener(new View.OnClickListener() {
                                              @Override
                                              public void onClick(View view) {

                                                  mActivity.mCurrentTab = MyConstants.TAB_CREATE;
                                                  mActivity.mStacks.get(mActivity.mCurrentTab).clear();
                                                  mActivity.fragment = new CreateScheduleFragment();
                                                  mActivity.pushFragments(mActivity.mCurrentTab, mActivity.fragment, false, true);
                                                  mActivity.title = getString(R.string.create_schedule);
                                              }
                                          }

    );

Now from Inside the ScheduleFragment() fragment i have a button which opens a new fragment

 activity.mCurrentTab = MyConstants.TAB_SCHEDULE_DETAILS;
    activity.fragment = new FragmentScheduleDetails();
    activity.pushFragments(activity.mCurrentTab, activity.fragment, false, true);
    activity.title = activity.getString(R.string.schedule_details);


 public boolean onBackPressed(){

    return true;
}

if i click back button from this FragmentScheduleDetails() fragment it is taking me back to the home screen but i am trying to go to the ScheduleFragment().

Please correct me. I am definitely going in a wrong way.

Thanks

Shahid Aleem
  • 73
  • 1
  • 1
  • 8

3 Answers3

0

If you want flow as A->B->c-> then on backpressed A->B

so you should write

ft.addToBackStack(null);

in pushFragment() method before

ft.commit();

Chetan Shelake
  • 656
  • 1
  • 6
  • 14
0

This is working exactly as you wrote. You can split navigation logic in simple steps.

Step 1. You click on layout_schedule which opens ScheduleFragment. What is the state after this action? mCurrentTab = MyConstants.TAB_SCHEDULE and mStack.get(MyConstants.TAB_SCHEDULE).size() == 1

Step 2. You click and open FragmentScheduleDetails. What is the state after this action? mCurrentTab = MyConstants.TAB_SCHEDULE_DETAILS and mStack.get(MyConstants.TAB_SCHEDULE).size() == 1

Step 3. You click Back button. At this point you fall into the branch mStacks.get(mCurrentTab).size() == 1, because mCurrentTab = MyConstants.TAB_SCHEDULE_DETAILS. And in this branch you call displayView(0), which effectively shows home screen.

I guess you wanted to implement Instagram-like navigation. In this case you should use only tags of root views as keys for mStacks and operate on some field called mCurrentRoot. Or better to use the lib like this https://github.com/ncapdevi/FragNav

nikis
  • 11,166
  • 2
  • 35
  • 45
  • displayView(0) will be called only once because i am working with single activity. And the displayView(0) is written under OnCreate() method. – Shahid Aleem Aug 13 '18 at 07:03
  • @ShahidAleem it is called at least twice: in `onCreate` and also during your back navigation, check step #3. – nikis Aug 13 '18 at 07:59
-1

You can add your fragments to stack with ft.addToBackStack("fragment-name") for handling back button. https://developer.android.com/training/implementing-navigation/temporal

Ehsan Mashhadi
  • 2,568
  • 1
  • 19
  • 30
  • I guess OP wants his own navigation logic, Instagram-like, which is not possible with naive `addToBackStack` calls. – nikis Aug 08 '18 at 13:09