Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openOptionsMenu() will not work in appcompat-v7 22.1.0 or newer

I've seen several reports of issues where openOptionsMenu() will not work on various Android versions, eg:

openOptionsMenu() across android versions

openOptionsMenu() not working

but the issue I have seems to be related to the version of the appcompat-v7 support library being used.

In essence, with the newer versions of appcompat-v7 the menu will appear fine when openOptionsMenu() is called if your activity extends Activity but will not work if you extend ActionBarActivity or AppCompatActivity (ie use the compatibility library). In older versions of appcompat-v7 it works fine.

It is reproducible, as follows:

  1. In Android Studio, Import Sample 'ActionBarCompat-Basic'
  2. Add a button to the screen, which invokes openOptionsMenu()
  3. Note that this works fine, as the old version of the library, appcompat-v7:21.0.3 is used in the sample
  4. Change the dependency to use appcompat-v7:23.0.1, rebuild, and when clicking on the button the menu will not appear.
  5. Change the main activity to extend Activity (ie no app compatability) - it works
  6. Change the main activity to extend AppCompatActivity (ie using app compatibility libarry) - it fails

After some testing, I've found that this stopped working in appcompat-v7:22.1.0, and will no longer work in any newer version of this jar.

This behaviour is identical on the emulator and on a physical device, and on Android versions 5.1.1(23) and 2.1(7) which were the two versions I tested it with.

I've added a comment to this bug: Android issue tracker bug

Any suggestions, ideas or workarounds appreciated!

-Steve

like image 939
Steve Moseley Avatar asked Sep 14 '15 23:09

Steve Moseley


1 Answers

I think I may have actually found a workaround for this. It involves overriding the openOptionsMenu() method:

@Override
public void openOptionsMenu()
{
    mActionBar.showOverflowMenu();
}

In order for showOverflowMenu() to work on devices with a physical menu key that are below API 19, use this: How to force action bar overflow icon to show

mActionBar is assigned as such:

android.support.v7.widget.Toolbar mActionBar = (android.support.v7.widget.Toolbar) getActionBar(getWindow().getDecorView())

This is the getActionBar() method:

public static ViewGroup getActionBar(View view)
{
    try
    {
        if (view instanceof ViewGroup)
        {
            ViewGroup viewGroup = (ViewGroup) view;

            if (viewGroup instanceof android.support.v7.widget.Toolbar)
            {
                return viewGroup;
            }

            for (int i = 0; i < viewGroup.getChildCount(); i++)
            {
                ViewGroup actionBar = getActionBar(viewGroup.getChildAt(i));

                if (actionBar != null)
                {
                    return actionBar;
                }
            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    return null;
}

Calling openOptionsMenu() from an AppCompatActivity now works!

NOTE: I tested this on API 26, but seeing as the getActionBar() method works far below that, I see no reason the rest of this will fail.

like image 120
TheWanderer Avatar answered Oct 17 '22 08:10

TheWanderer