Implementing proper back navigation and home button handling using Toolbar in Android

前端 未结 6 1834
粉色の甜心
粉色の甜心 2021-01-30 23:31

I am using a single activity and multiple fragments(screenshot attached) within the same activity to provide a seamless navigation. But after implementing the latest toolbar and

6条回答
  •  故里飘歌
    2021-01-31 00:24

    Ok, after a lot of tests I finally succeeded to setup a good navigation. I needed exactly the same as you, the only difference is that I am using v4 Fragments, but I don't think this will change anything here.

    I am not using ActionBarDrawerToggle since the latest examples from Google do not use this component anymore.

    The solution below also works for deep navigation: parent activity --> fragment --> fragment etc.

    The only change needed in the Fragments is to change the title:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    
        getActivity().setTitle(R.string.targets);
    }
    

    In the parent Activity onCreate method, I initialize the following:

        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
        setupDrawerContent(mNavigationView);
    
        final Toolbar toolbar = (Toolbar) findViewById(R.id.drawer_toolbar);
        setSupportActionBar(toolbar);
    
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_24);// Set the hamburger icon
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);// Set home button pressable
    
        // Handle the changes on the actionbar
        getSupportFragmentManager().addOnBackStackChangedListener(
                new FragmentManager.OnBackStackChangedListener() {
                    public void onBackStackChanged() {
                        // When no more fragments to remove, we display back the hamburger icon and the original activity title
                        if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
                            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_24);
                            setTitle(R.string.app_name);
                        }
                        // Else displays the back arrow
                        else {
                            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_back_24);
                        }
                    }
                });
    

    Here is now the code to handle the action on the Home button:

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        // Close the soft keyboard right away
        Tools.setSoftKeyboardVisible(mViewPager, false);
    
        switch (item.getItemId()) {
            case android.R.id.home:
    
                // When no more fragments to remove, open the navigation drawer
                if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
                    mDrawerLayout.openDrawer(GravityCompat.START);
                }
                // Removes the latest fragment
                else {
                    getSupportFragmentManager().popBackStack();
                }
    
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

    And finally the code to handle the back press action:

    @Override
    public void onBackPressed() {
        // When no more fragments to remove, closes the activity
        if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
            super.onBackPressed();
        }
        // Else removes the latest fragment
        else {
            getSupportFragmentManager().popBackStack();
        }
    }
    

    NOTE: I am using an AppCompatActivity, a NavigationView and the theme Theme.AppCompat.Light.NoActionBar.

提交回复
热议问题