Search code examples
androidandroid-fragmentsandroid-actionbarandroid-toolbar

How to manage ActionBar title and icon when working with Fragments hosted by one Activity?


I have many Fragments all hosted by one Activity. Activity has ActionBar with Toolbar, DrawerLayout and menu_icon to open on close drawer. In one Fragment I show list of items, and when users clicks on one I am showing DetailFragment for that item.

What I want is to replace menu_icon when user is in DetailFragment to back_icon and set appropriate title, and when user clicks on this back_icon I want to pop that DetaiFragment from backstack and again show home_icon. So Click on home and back icons have to behave differently depending on current Fragment.

And I don't want to use Activity for DetailFragment. Is there is a way to manage ActionBar icons and actions in one place (hosting Activity)?


Solution

  • I found the answer here: https://stackoverflow.com/a/20314570/5222156

    In onCreate on hosting Activity, after setting up Toolbar and Drawer I initialized listener for changes in backstack

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupToolbar(R.drawable.ic_menu);
        setupNavigationDrawer();
    
        getSupportFragmentManager().addOnBackStackChangedListener(this);
    }
    

    The rest of the code looks almost the same as in the original answer:

    @Override
    public void onBackStackChanged() {
        shouldDisplayHomeUp();
    }
    
    public void shouldDisplayHomeUp() {
        //Enable Up button only  if there are entries in the back stack
        FragmentManager fragmentManager = getSupportFragmentManager();
        int count = fragmentManager.getBackStackEntryCount();
    
        Fragment fr = fragmentManager.findFragmentById(R.id.flContent);
        String tag = fr.getTag();
    
        boolean canGoBack = count > 0;
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeAsUpIndicator(canGoBack ? R.drawable.ic_arrow_back : R.drawable.ic_menu);
            actionBar.setTitle(tag);
        }
    }
    
    @Override
    public boolean onSupportNavigateUp() {
        boolean canGoBack = getSupportFragmentManager().getBackStackEntryCount() > 0;
    
        if (canGoBack) {
            navigationController.navigateBack();
        } else {
            mDrawerLayout.openDrawer(Gravity.START);
        }
        return true;
    }
    
    @Override
    public void onBackPressed() {
        if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
            closeDrawer();
        } else {
            super.onBackPressed();
        }
    }