在新版本的Android(3.x及以上)中处理缺失的菜单按钮

40
我喜欢Android在3.0之前使用的菜单按钮,因为对于我的游戏应用非常有用。它使我能够将重要但与游戏无关的功能(保存游戏、参考信息链接)放在不会混乱主游戏界面的地方,但仍然很容易访问(选项菜单)。
这种按键的使用在3.0中成为了一个问题,因为它移除了MENU按钮并用操作栏替换了它。操作栏对于喜欢运行全屏幕的游戏来说确实不太合适,所以这是一个真正的麻烦。没有操作栏 - 就无法访问选项菜单。然而,我可以一段时间忽略它,因为我在平板电脑上没有那么多用户,并且缺乏测试的时间。
然而,ICS使这成为一个严重的问题,因为MENU按钮显然不会回来了。现在我不仅必须在平板电脑上处理这些问题,还必须在手机上处理。
我解决这个问题的最初方法是简单地在我的GUI中放置一个软按钮来替代硬MENU按钮。
this.openOptionsMenu();

在ICS中,一切都恢复正常了。

然而,在Honeycomb上,如果ActionBar不可见,则调用openOptionsMenu将完全没有任何作用。

有什么想法来处理这个问题吗?

  • 我想我可以回到使用TargetSDK<11(从而强制ActionBar出现在平板电脑上),但据我所见,这仅仅是把问题推向未来,我不希望这样做。

  • 完全放弃选项菜单,转而只使用上下文菜单? [澄清:我的意思是,我仅使用上下文菜单,而不是打开选项菜单,因为目前至少这些在所有设备上都有效]。

很想听听其他遇到类似Options Menu / ActionBar混乱问题的人是如何决定的。


嗯,我不太确定,但我有一台平板电脑,底部的那个栏(叫什么来着,我猜不是操作栏,因为那个在顶部?)不会消失(它是带有主页、返回等按钮的那个;实际上,它可能不会消失,这是由操作系统强制执行的)。很多应用程序会在那里出现一个选项按钮!你不能做同样的事情吗?虽然我没有使用过,所以不知道如何制作... 编辑:阅读一下...你是说回到使用TargetSDK < 11吗? - Dominik Bucher
假设你在谈论操作栏,那么是的。 - Michael A.
你能告诉我你的应用程序在uses-sdk中使用的targetSdkVersion是多少吗? - havexz
1
不是很确定(现在不在我的开发机器上),但应该是14或15。我喜欢保持目标SDK相对较新,尽管我仍然支持Android 1.5。 - Michael A.
6个回答

18
让我分享另一个场景,即使不是游戏,菜单按钮也变得至关重要。
我有一个应用程序实现了自己的工具栏,这些工具栏在某种程度上表现得像ActionBar。好吧,我这样做是因为我的应用程序是在1.5 sdk发布的。那时还没有这样的概念。为了适应我的工具栏,我隐藏了默认标题栏。但是一些操作是通过菜单功能完成的。
现在由于Galaxy Nexus没有菜单按钮,如果您没有使用ActionBar,这会对我造成伤害,因为我的应用程序仍然支持1.5。
好吧,有各种解决方法,但没有一种易于解决的方法。
话虽如此,我唯一想到的解决方法是在我的工具栏上为用户提供所有选项,因此根本不需要菜单。我可以这样做,因为只有两个操作不属于工具栏。
在您的情况下,在游戏中为按钮上的上下文菜单并不是一个坏的解决方案,因为游戏只有一个上下文,而不是在列表项上的上下文菜单,其中每个项都是不同的上下文。

顺便提一句,如果openOptionsMenu在ICS上可用,而且你可以在一段时间后放弃HoneyComb(即使现在用户基数太低),那么尝试给两个菜单基于版本

编辑:还有另一种方法可以在下面的导航栏中获得MENU软件按钮。只需将targetSdkVersion设置为小于11即可。更多详情请阅读整个解决方案


重新编辑。这是我上面的第一选择,但是你也会得到ActionBar,而我绝对不想要它。 - Michael A.
好的,动作栏(Action Bar)和导航栏(Navigation Bar)是两件不同的事情。动作栏通常在顶部,导航栏在底部,可以参考这里的链接(http://techblog.rokoder.com/android-missing-menu-button/)。那么您想要去掉哪一个?顺便提一句,在您的情况下,您并不依赖Holo主题之类的,因为您有一个游戏。 - havexz
正如文本所述 - 问题在于用ActionBar替换MENU。但是我忽略了MENU出现在导航栏中的部分。非常有趣,谢谢 - 我以前没有注意到这一点,它确实适用于ICS(将不得不检查Honeycomb)。这肯定会帮助暂时避免问题,尽管我想知道我们能够依赖Android操作系统继续支持这个功能多久。 - Michael A.
只要大多数设备迁移到4.0,那么一切都应该没问题。因此,当支持不再存在时,大多数受众将转移到新平台,您无需支持<4.0。我认为4.0中的API /模式比前任更加成熟,它们会保持更长时间的使用。 - havexz
当然可以这样希望,尽管我必须说,到目前为止,谷歌在这方面的记录并没有让我感到鼓舞。不过,对于一般情况来说,这是很好的建议 - 如果我可以多次点赞,我会这么做的。 - Michael A.
显示剩余4条评论

2
然而ICS使这成为一个严重的问题,因为菜单按钮显然不会回来。更准确地说,是否有类似菜单的屏幕外按钮取决于设备制造商。引用Android 4.0的兼容性定义文档:
“主页、菜单和返回功能对于Android导航范例至关重要。当运行应用程序时,设备实现必须随时向用户提供这些功能。这些功能可以通过专用物理按钮(例如机械或电容触摸按钮)实现,也可以使用专用软件键、手势、触摸面板等实现。”
因此,不能指望有屏幕外菜单按钮,尽管可能会有。
如何解决这个问题?在游戏UI中编写自己的“菜单”。我不认为一个需要全屏幕的游戏会使用选项菜单——事实上,我从未见过这样的游戏(尽管我不是一个大型游戏玩家)。我玩过的所有游戏在按下菜单键时什么都不做。相反,任何可能被视为“菜单”的东西都直接在游戏UI中实现(例如,一个按钮导致一个屏幕,在游戏UI的外观和感觉下格式化,提供选择要做的事情)。
完全放弃选项菜单,只使用上下文菜单会很糟糕,因为用户不知道在哪里长按才能呼出菜单。

3
“设备实现必须在运行应用程序时始终向用户提供这些功能。” - 鉴于谷歌自己的Galaxy Nexus根本没有做到这一点,因此这句话根本没有任何意义。 - Michael A.
1
这将是糟糕的,因为用户不知道在哪里长按才能弹出菜单。他们会知道要按标有“菜单”的按钮,这将弹出上下文菜单,而不是像我现在这样只在非3.x设备上出现的选项菜单。 - Michael A.
1
嗯...你所指的菜单按钮是什么?在我的手机上,我总是可以精确地访问三个按钮(从左到右):返回、主页和最近使用的应用程序按钮。如果你(和CDD文档)所指的是后者作为菜单按钮,那么我们可能会有点误解:我所指的是原始的菜单按钮范例(至少在Android 2.3版本之前使用),这显然不是ICS中相同的GUI范例。当然,这也是问题的本质 - 如何最好地处理跨操作系统版本根本性地改变的GUI范例。 - Michael A.
补充一下CommonsWare的帖子,CDD实际上禁止制造商在屏幕底部的导航栏中有一个菜单按钮。 - user1076637
如果targetSdkVersion < 10(或者如果未指定targetSdkVersion且minSdkVersion < 10),则Galaxy Nexus将在导航区域显示一个第四个菜单按钮,形式为右侧的三个点。这是由Android CDD 4.0规定的,以实现与旧版应用程序的向后兼容性。这也会导致应用程序具有传统的外观和感觉(例如,在设置页面中)。 - user1076637
显示剩余3条评论

2

0
Michael,我曾经遇到过同样的问题,并通过使用自定义对话框来实现我的选项菜单解决了它。在ICS上,它比底部的传统选项菜单看起来更好。配置如下:
minSdkVersion = 8 targetSdkVersion = 14 SDK构建版本8(在eclipse设置中可以设置为14,但我喜欢它提供的类型安全性)
API小于10的用户使用硬件菜单按钮并查看标准选项菜单。 API大于等于10的用户在应用程序中看到三个点图标(溢出菜单),单击后会得到我的自定义对话框菜单。他们还可以在设置等中看到新的ICS外观。
似乎菜单按钮不会回来,尽管只有不到1%的用户使用ICS,但我想打破传统障碍。

0

针对最近的博客文章,他们似乎希望开发人员开始使用操作栏(Action Bars)而非菜单(Menus),但是如果想要支持API=>3.0和API<3.0就会变得很麻烦。所以,要么创建一个与API<3.0兼容的自定义操作栏(您可以在SDK中找到示例),要么......我上周正在尝试这个:

我还遇到了一个问题,即ICS平板电脑上的菜单按钮没有出现,我相信当时我将targetSdk设置为11,因为我想实现ActionBar。然后,我将minSdk设置为3,targetSdk设置为4。ActionBar和菜单溢出按钮都出现了。所以,这是现在的解决方法(至少适用于我正在处理的项目)。


-2

我为3.x版本添加了特殊逻辑。 只有在这些版本中,我才使用操作栏。

            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB
             || Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB_MR1
             || Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB_MR2) {
                requestWindowFeature(Window.FEATURE_ACTION_BAR);        
            }
            else{
//              hide the status bar, do not use action bar         
                requestWindowFeature(Window.FEATURE_NO_TITLE);    
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);               
            }

对于所有其他版本,我显示自己的菜单按钮并在全屏模式下运行我的游戏。当按下我的菜单按钮时,我使用以下代码行,其中“act”是当前活动。

act.openOptionsMenu();

作为您的菜单xml的一部分,请确保有以下行来设置“showAsAction”
showAsAction="ifRoom"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接