Android 5.0 Toolbar fragment backstack

1.2k Views Asked by At

I've used the new Toolbar from the appcompat library to replace the action bar, and have set it up as one might expect with a navigation drawer.

My problem is that pressing back minimises the app instead of cycling through the backstack. If I manually add logic to onBackPressed() to pop the back stack, that's one solution, but messes with the navigation drawer's currently selected item.

activity_main.xml

<LinearLayout>

    <android.support.v7.widget.Toolbar/>

    <android.support.v4.widget.DrawerLayout>

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <ListView android:id="@+id/navigation_drawer"/>

    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

MainActivity.java

private void setupDrawerAndToolbar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
        R.string.app_name, R.string.app_name);
    drawerLayout.setDrawerListener(toggle);

    drawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            onNavigationDrawerItemSelected(position, true);
            drawerLayout.closeDrawer(GravityCompat.START);
        }
    });
    List<NavigationDrawerItem> items = new ArrayList<>();
    items.add(...);
    drawerList.setAdapter(new NavigationDrawerAdapter(this, items));
    drawerList.setItemChecked(selectedIndex, true);
}

...

private void onNavigationDrawerItemSelected(int position, boolean addToBackStack) {
    if (position == selectedIndex) {
        return;
    }
    selectedIndex = position;

    // update the main content by replacing fragments
    FragmentManager manager = getFragmentManager();

    Fragment fragment;

    switch (position) {
        case ...:
            fragment = new Fragment();
            break;
        default:
            throw new IllegalArgumentException("invalid position");
    }

    FragmentTransaction transaction =
        manager.beginTransaction()
               .replace(R.id.container, fragment);

    if (addToBackStack) {
        transaction.addToBackStack(fragment.getClass().getName());
    }

    transaction.commit();
}
1

There are 1 best solutions below

0
On BEST ANSWER

Came up with a workaround:

private void onNavigationDrawerItemSelected(int position, boolean addToBackStack) {
    if (position == selectedIndex) {
        return;
    }

    // update the main content by replacing fragments

    Fragment fragment;

    switch (position) {
        case ...:
            fragment = new Fragment();
            break;
        default:
            throw new IllegalArgumentException("invalid position");
    }

    FragmentTransaction transaction =
        getFragmentManager().beginTransaction()
                            .replace(R.id.container, fragment, fragment.getClass().getName());

    if (addToBackStack) {
        transaction.addToBackStack(String.valueOf(selectedIndex));
    }

    transaction.commit();
    selectedIndex = position;
}

...

@Override
public void onBackPressed() {
    int count = getFragmentManager().getBackStackEntryCount();
    if (count > 0) {
        int index = Integer.parseInt(
            getFragmentManager().getBackStackEntryAt(count - 1).getName());
        getFragmentManager().popBackStack();
        selectedIndex = index;
        return;
    }
    super.onBackPressed();
}