Search code examples
javaandroidandroid-actionbarandroid-navigation

How to access "Up" button in onPrepareOptionsMenu and toggle its visibility at runtime


I want to toggle the visibility of the "Up" button (the left arrow) on ActionBar at runtime. I tried to access the button in onPrepareOptionsMenu using the item id R.id.home since this id works in onOptionsItemSelected, however I keep getting IndexOutOfBoundsException for that particular line in onPrepareOptionsMenu on activity's creation. What is the correct item id for the "Up" button? Or is there a better way to toggle the "Up" button at runtime?

Here is my code:

public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem up = menu.getItem(R.id.home);
    if (phase != Phase.IDLE) {  // this is the runtime situation in which I want to disable the Up navigation
        up.setVisible(false);
    } else {
        up.setVisible(true);
    }

    return true;
}

I have also tried android.R.id.home, got the same error.


Solution

  • I found the solution through Android documentation and thought it would be better to post it back here. Although none of the other answers fully worked in toggling the Up button (at least not on the platform I was working with), some of them (and the comments) were quite helpful, especially in pointing me to using ActionBar.setDisplayHomeAsUpEnabled(). However, the key here is a call to invalidateOptionsMenu() that forces the menu to be redrawn.

    To quote the documentation:

    On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the app bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().

    So my final solution is:

    • Store the ActionBar as an instance variable (thanks to @rupinderjeet);
    • Call setDisplayHomeAsUpEnabled() on the ActionBar whenever I want to toggle the Up button;
    • Call invalidateOptionsMenu() immediately after each call to setDisplayHomeAsUpEnabled().