1

I have implemented NavigationView in Android with fragments. This is my first time dealing with fragments. The problem is I have 3 Items in NavigationView and want to do something like that:

  1. User enters home screen and "Top 20 Fragment" is selected by default (in this moment back key makes app exit) - I am setting this fragment as default without pulling transaction to back stack,
 private void setStartingFragment(NavigationView navigationView,
                                     FragmentManager fragmentManager) {
        Fragment fragment = null;
        Class fragmentClass = Top20RecipesFragment.class;

        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frame_layout_content, fragment);
        fragmentTransaction.commit();

        MenuItem menuItem = navigationView.getMenu().getItem(0);
        menuItem.setChecked(true);      // Highlight The Selected Item
        setTitle(menuItem.getTitle());  // Updating Toolbar Title
    }

When I pick one of 2 other fragments I would like them to add to back stack. I want to do this like in Twitch mobile application. Possibilities are:

  • 2nd Fragment (or 3rd) -> Home fragment -> Exit or
  • 2nd Fragment -> 3rd Fragment -> Home Fragment -> Exit or
  • 2nd Fragment -> 3rd Fragment -> Home Fragment -> Exit or

Another big problem is to sync NavigationView selected item and Tooblar title on back button pressed.

Here is what I have for now if we talk about NavigationView and fragments replacing:

// Replace Existing Fragment With a New One
    public void selectDrawerItem(MenuItem menuItem) {
        Fragment fragment = null;
        Class fragmentClass = null;

        switch(menuItem.getItemId()) {
            case R.id.nav_top20_recipes: {
                fragmentClass = Top20RecipesFragment.class;
                break;
            }

            case R.id.nav_kitchen_type: {
                fragmentClass = KitchenTypeFragment.class;
                break;
            }
            case R.id.nav_meal_type: {
                fragmentClass = MealTypeFragment.class;
                break;
            }
        }

        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frame_layout_content, fragment);
        fragmentTransaction.addToBackStack(Integer.toString(fragment.getId()));
        fragmentTransaction.commit();

        menuItem.setChecked(true);      // Highlight The Selected Item
        setTitle(menuItem.getTitle());  // Updating Toolbar Title
        mDrawerLayout.closeDrawers();   // Close The Drawer
    }

I looked into Android official site and they advice to use OnBackStackChangedListener to change Activity apperance according to fragment replacing and using back button.

I tried to apply this interface and here what I tried to do with different toutorials but app crashes or does not work properly.

// Managing Fragments In Back Stack
    @Override
    public void onBackStackChanged() {
        int actualStackHeight = getSupportFragmentManager().getBackStackEntryCount();

        if (actualStackHeight > 0) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            int fragmentId = fragmentManager.getBackStackEntryAt(actualStackHeight - 1).getId();
            Fragment currentFragment = fragmentManager.findFragmentById(fragmentId);

            switch (currentFragment.getId()) {
                case R.id.top20_fragment: {
                    MenuItem menuItem = nvDrawer.getMenu().getItem(0);
                    menuItem.setChecked(true);      // Highlight The Selected Item
                    setTitle(menuItem.getTitle());  // Updating Toolbar Title
                }

                case R.id.kitchen_type_fragment: {
                    MenuItem menuItem = nvDrawer.getMenu().getItem(1);
                    menuItem.setChecked(true);      // Highlight The Selected Item
                    setTitle(menuItem.getTitle());  // Updating Toolbar Title
                }

                case R.id.meal_type_fragment: {
                    MenuItem menuItem = nvDrawer.getMenu().getItem(2);
                    menuItem.setChecked(true);      // Highlight The Selected Item
                    setTitle(menuItem.getTitle());  // Updating Toolbar Title
                }
            }
        } else {
            finish();
        }
    }

This is my first time dealing with something like this so please try to understand me. I've searched for different ansewers even here on stack but non of them helped me :/

anton86993
  • 638
  • 1
  • 9
  • 26
  • 1
    This problem has already been discussed here http://stackoverflow.com/questions/27824642/update-selected-state-of-navigation-drawer-after-back-press – Kshitij Aggarwal Jan 03 '16 at 06:02

1 Answers1

1

If you are using NavigationView use it with the Navigation API. Then, on your onCreate(..) method...

main_navigationview.setupWithNavController(
    findNavController(R.id.main_nav_container)
)
findNavController(
    R.id.main_nav_container
).addOnDestinationChangedListener {
    controller, destination, bundle ->
        main_navigationview.setCheckedItem(destination.id)
}

Then, the NavigationView will be in sync, as simple as that.

miguelt
  • 384
  • 4
  • 8