androidandroid-actionbarnavigation-drawerandroid-navigationup-navigation

Up navigation not appearing, when opening Fragments not in runtime


The application consists of 1 Activity with a NavigationDrawer and we can open Fragments in a 2 level hierarchy also. In the latter case, we have a Back Button on the ActionBar to implement up navigation.
Everything works fine at runtime, if we open the fragments in the 2 level hierarchy by click events, but when we do the same from code - with also the same code -, the navigation button won't show up. The navigation still works. If we navigate back to the home level, the NavigationBar's hamburger icon show up, and if we open the Fragments in the 2 level hierarchy by click events, then the back button show up instead of the hamburger icon as it should.
In short: everything works fine again, if we navigate back to the home level.

The related methods:

private void shouldDisplayHomeAsUp() {
  FragmentManager fragmentManager = getSupportFragmentManager();
  boolean shouldDisplay = fragmentManager.getBackStackEntryCount()>0;
  ActionBar actionBar = getSupportActionBar();
  if (actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(shouldDisplay);
    CharSequence actionBarTitle = actionBar.getTitle();
    if (isMainListFragment(shouldDisplay, actionBarTitle)) {
      actionBar.setTitle(R.string.app_name);
      setDrawerEnabled(true);
    }
  }
}

private void setDrawerEnabled(boolean enabled) {
  if (!enabled) {
    disableDrawer();
    enableActionBarBackNavigation();
  } else {
    enableDrawer();
  }
}

private void disableDrawer() {
  drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
  actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
  actionBarDrawerToggle.syncState();
}

private void enableDrawer() {
  drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
  actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
  actionBarDrawerToggle.syncState();
}

private void enableActionBarBackNavigation() {
  actionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
      onBackPressed();
    }

  });
}

The shouldDisplayHomeAsUp() method called by the onBackStackChanged(), but there is no difference, when we call it in a static manner.
Mostly we call the actionBar.setDisplayHomeAsUpEnabled() and actionBarDrawerToggle.setDrawerIndicatorEnabled(false) methods.

See the below pictures: left is the proper one

If we set a reminder in the application, it will trigger a notification. When we click on the notification, it open the main screen - home level -, the a list - as You can see above -, and then a detaild view of notification related todo. Then we can navigate back in the view hierarchy. That is the purpose to open the fragments programmatically.


Solution

  • I solved the problem.
    Modified the method like this:

    private void shouldDisplayHomeAsUp() {
      FragmentManager fragmentManager = getSupportFragmentManager();
      boolean shouldDisplay = fragmentManager.getBackStackEntryCount()>0;
      ActionBar actionBar = getSupportActionBar();
      if (actionBar != null) {
        if (shouldDisplay) {
          setDrawerEnabled(false);
          actionBar.setDisplayHomeAsUpEnabled(true);
        } else {
          actionBar.setDisplayHomeAsUpEnabled(false);
          setDrawerEnabled(true);
        }
    
        CharSequence actionBarTitle = actionBar.getTitle();
        if (isMainListFragment(shouldDisplay, actionBarTitle)) {
          actionBar.setTitle(R.string.app_name);
          actionBar.setDisplayHomeAsUpEnabled(false);
          setDrawerEnabled(true);
        }
      }
    }
    

    The order of setDrawerEnabled(false) and actionBar.setDisplayHomeAsUpEnabled(true) method calls are very important. That was the root cause of the problem.