我希望所有无法适应ActionBar的菜单项都进入溢出菜单(从ActionBar而不是菜单按钮中访问),即使在有菜单按钮的设备上也是如此。对用户来说,这似乎比将它们抛到需要用户从触摸(屏幕)交互跳转到基于按钮的交互的单独菜单列表中要更直观。
在模拟器中,我可以将“硬件返回/主页键”值设置为“否”,以获得此效果。 我已经搜索了一种在具有菜单按钮但找不到的实际设备上执行此操作的方法。 有人能帮我吗?
我希望所有无法适应ActionBar的菜单项都进入溢出菜单(从ActionBar而不是菜单按钮中访问),即使在有菜单按钮的设备上也是如此。对用户来说,这似乎比将它们抛到需要用户从触摸(屏幕)交互跳转到基于按钮的交互的单独菜单列表中要更直观。
在模拟器中,我可以将“硬件返回/主页键”值设置为“否”,以获得此效果。 我已经搜索了一种在具有菜单按钮但找不到的实际设备上执行此操作的方法。 有人能帮我吗?
你也可以使用这个小技巧:
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ignored) {
}
建议将这段代码放在你的应用程序类的onCreate
方法中。
这将强制应用程序显示溢出菜单。菜单按钮仍然可以工作,但它会在右上角打开菜单。
[编辑] 因为它已经多次出现:这个技巧只适用于Android 3.0引入的本机ActionBar,而不是ActionBarSherlock。后者使用自己的内部逻辑来决定是否显示溢出菜单。如果您使用ABS,则所有平台<4.0都由ABS处理,因此受到其逻辑的影响。该技巧仍将适用于所有Android 4.0或更高版本的设备(您可以安全地忽略Android 3.x,因为几乎没有带有菜单按钮的平板电脑)。
存在一个特殊的ForceOverflow主题,可以强制ABS中的菜单,但显然它会因为一些问题在将来的版本中被删除。
编辑:修改以回答物理菜单按钮的情况。
这实际上是由设计防止的。根据Android 设计指南中的兼容性部分:
"...操作溢出可从菜单硬件键中获得。 所显示的操作弹出窗口...将显示在屏幕底部。"
您会注意到,在截图中,具有物理菜单按钮的手机在ActionBar中没有溢出菜单。这避免了用户的歧义,本质上有两个可用于打开完全相同菜单的按钮。
为了解决设备间一致性问题:对于用户体验来说,最重要的是您的应用与同一设备上的所有其他应用程序的行为一致,而不是在所有设备上都表现一致。
我曾经通过定义我的菜单来解决这个问题(在我的示例中也使用了ActionBarSherlock图标):
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_overflow"
android:icon="@drawable/abs__ic_menu_moreoverflow_normal_holo_light"
android:orderInCategory="11111"
android:showAsAction="always">
<menu>
<item
android:id="@+id/menu_overflow_item1"
android:showAsAction="never"
android:title="@string/overflow_item1_title"/>
<item
android:id="@+id/menu_overflow_item2"
android:showAsAction="never"
android:title="@string/overflow_item2_title"/>
</menu>
</item>
</menu>
我承认这可能需要在您的xml中手动进行"溢出管理",但我发现这个解决方案很有用。
您还可以在您的活动中强制设备使用硬件按钮来打开溢出菜单:
private Menu mainMenu;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO: init menu here...
// then:
mainMenu=menu;
return true;
}
@Override
public boolean onKeyUp(int keycode, KeyEvent e) {
switch(keycode) {
case KeyEvent.KEYCODE_MENU:
if (mainMenu !=null) {
mainMenu.performIdentifierAction(R.id.menu_overflow, 0);
}
}
return super.onKeyUp(keycode, e);
}
:-)
如果您正在使用支持库中的操作栏(android.support.v7.app.ActionBar
),请使用以下内容:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yorapp="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/menu_overflow"
android:icon="@drawable/icon"
yourapp:showAsAction="always"
android:title="">
<menu>
<item
android:id="@+id/item1"
android:title="item1"/>
<item
android:id="@+id/item2"
android:title="item2"/>
</menu>
</item>
</menu>
<item android:id="@+id/pick_action_provider"
android:showAsAction="always"
android:title="More"
android:icon="@drawable/ic_action_overflow"
android:actionProviderClass="com.example.AppPickActionProvider" />
package com.example;
import android.content.Context;
import android.util.Log;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;
public class AppPickActionProvider extends ActionProvider implements
OnMenuItemClickListener {
static final int LIST_LENGTH = 3;
Context mContext;
public AppPickActionProvider(Context context) {
super(context);
mContext = context;
}
@Override
public View onCreateActionView() {
Log.d(this.getClass().getSimpleName(), "onCreateActionView");
return null;
}
@Override
public boolean onPerformDefaultAction() {
Log.d(this.getClass().getSimpleName(), "onPerformDefaultAction");
return super.onPerformDefaultAction();
}
@Override
public boolean hasSubMenu() {
Log.d(this.getClass().getSimpleName(), "hasSubMenu");
return true;
}
@Override
public void onPrepareSubMenu(SubMenu subMenu) {
Log.d(this.getClass().getSimpleName(), "onPrepareSubMenu");
subMenu.clear();
subMenu.add(0, 1, 1, "Item1")
.setIcon(R.drawable.ic_action_home).setOnMenuItemClickListener(this);
subMenu.add(0, 2, 1, "Item2")
.setIcon(R.drawable.ic_action_downloads).setOnMenuItemClickListener(this);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId())
{
case 1:
// What will happen when the user presses the first menu item ( 'Item1' )
break;
case 2:
// What will happen when the user presses the second menu item ( 'Item2' )
break;
}
return true;
}
}
我不确定这是否是您正在寻找的,但我在ActionBar的菜单中构建了一个子菜单,并将其图标设置为与Overflow菜单的图标相匹配。尽管它不会自动发送项目(即您必须选择什么始终可见和什么始终溢出),但我认为这种方法可能会对您有所帮助。
如果这个问题已经过时,非常抱歉。
以下是我解决错误所做的步骤。我进入布局并创建了两个包含工具栏的布局。一个是针对sdk版本8的布局,另一个是针对sdk版本21的布局。在版本8上,我使用了android.support.v7.widget.Toolbar,而在sdk 21布局中我使用了android.widget.Toolbar。
然后我在我的活动中填充工具栏。我检查sdk版本是否为21或更高版本。然后我填充相应的布局。这将强制硬件按钮映射到您实际设计的工具栏。
Field
,请选择这个java.lang.reflect.Field
;) - Eugene van der Merwe