简体   繁体   English

openOptionsMenu()在appcompat-v7 22.1.0或更新版本中不起作用

[英]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()无法在各种Android版本上运行的问题的报告,例如:

openOptionsMenu() across android versions 跨Android版本的openOptionsMenu()

openOptionsMenu() not working openOptionsMenu()不起作用

but the issue I have seems to be related to the version of the appcompat-v7 support library being used. 但我遇到的问题似乎与正在使用的appcompat-v7支持库的版本有关。

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). 本质上,使用较新版本的appcompat-v7,如果您的活动扩展了Activity,则调用openOptionsMenu()时菜单会很好,但如果您扩展ActionBarActivityAppCompatActivity (即使用兼容性库)则不会起作用。 In older versions of appcompat-v7 it works fine. 在较旧版本的appcompat-v7中,它可以正常工作。

It is reproducible, as follows: 它是可重复的,如下:

  1. In Android Studio, Import Sample 'ActionBarCompat-Basic' 在Android Studio中,导入示例'ActionBarCompat-Basic'
  2. Add a button to the screen, which invokes openOptionsMenu() 在屏幕上添加一个按钮,调用openOptionsMenu()
  3. Note that this works fine, as the old version of the library, appcompat-v7:21.0.3 is used in the sample 请注意,这样可以正常工作,因为样本中使用了旧版本的库appcompat-v7:21.0.3
  4. Change the dependency to use appcompat-v7:23.0.1, rebuild, and when clicking on the button the menu will not appear. 更改依赖关系以使用appcompat-v7:23.0.1,重建,单击按钮时菜单将不会出现。
  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 更改主要活动以扩展AppCompatActivity(即使用应用程序兼容性libarry) - 它失败

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. 经过一些测试后,我发现这已停止在appcompat-v7:22.1.0中运行,并且将不再适用于此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. 这种行为在模拟器和物理设备上是相同的,在Android版本5.1.1(23)和2.1(7)上是我测试过的两个版本。

I've added a comment to this bug: Android issue tracker bug 我添加了对此错误的评论: Android问题跟踪器错误

Any suggestions, ideas or workarounds appreciated! 任何建议,想法或变通方法表示赞赏!

-Steve 史蒂夫

I think I may have actually found a workaround for this. 我想我可能实际上找到了解决方法。 It involves overriding the openOptionsMenu() method: 它涉及重写openOptionsMenu()方法:

@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 为了使showOverflowMenu()能够在具有低于API 19的物理菜单键的设备上工作,请使用: 如何强制操作栏溢出图标以显示

mActionBar is assigned as such: mActionBar分配如下:

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

This is the getActionBar() method: 这是getActionBar()方法:

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! 从AppCompatActivity调用openOptionsMenu()现在可以正常工作!

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. 注意:我在API 26上对此进行了测试,但是当看到getActionBar()方法远远低于该方法时,我认为其余部分都没有失败。

More simple than The Wanderer's post and it goes fine in genymotion and also in my cell phone (marshmallow): 比The Wanderer的帖子更简单,它在genymotion和我的手机(棉花糖)中也很好:

import android.support.v7.widget.Toolbar;

//btMainMenu is a button
public void btMainMenu_click(View view) {
    final View view2 = getWindow().getDecorView().findViewById(R.id.action_bar);
    if (view2 instanceof Toolbar) {
        ((Toolbar) view2).showOverflowMenu();
    }
    else {
        System.out.println("What a pity!, it doesn't work..., view2 is not toolbar");
    }
}

https://issuetracker.google.com/issues/37060139 https://issuetracker.google.com/issues/37060139

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM