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)?
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();
}
}