我尝试了以下解决方案:ActionBarSherlock&HoloEverywhere-强制溢出?,但它不起作用,因为absForceOverflow不存在。它是在最新版本中被删除了吗?我已经检查了ABS和HE库项目的R文件,这个字段根本不存在。
我的应用程序主题设置为@style/Holo.Theme.Sherlock.Light,并且这就是我尝试继承并添加absForceOverflow参数设置为true的主题。
从ActionbarSherlock 4.2开始,我们失去了管理溢出菜单可见性的能力。 为使其正常工作,需要结合以下两种方法:
为了强制在Android 3.x (honeycomb)及以上版本中显示菜单,需要使用此hack + 添加检查Android版本的代码:
public static final int DEVICE_VERSION = Build.VERSION.SDK_INT;
public static final int DEVICE_HONEYCOMB = Build.VERSION_CODES.HONEYCOMB;
if (DEVICE_VERSION >= DEVICE_HONEYCOMB)
// Code from answer above
为早期的蜂巢之前设备打开菜单:
ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java
,进入方法reserveOverflow
用以下内容替换原来的内容:
public static boolean reserveOverflow(Context context) { return true; }
这将强制显示菜单...
但当点击菜单按钮时,菜单弹出窗口没有显示。为了实现这一点,我们需要在您的activity类中覆盖此操作:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (DEVICE_VERSION < DEVICE_HONEYCOMB) {
if (event.getAction() == KeyEvent.ACTION_UP &&
keyCode == KeyEvent.KEYCODE_MENU) {
openOptionsMenu();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
完成这些操作后,您应该拥有适用于所有Android版本的完全可用的溢出操作栏菜单。
正如Siddharth Lele指出的那样,在最新版的ABS中已经将其删除,以便与实际操作栏行为相同。因此,乍一看放弃显示此菜单是最佳选择。
然而,在某些设备上显示溢出菜单而在其他设备上不显示是Android操作栏中的一个设计缺陷,这是我个人的观点。原因如下:
在具有硬件菜单键的设备上,该菜单不会在操作栏中显示。大多数最新设备的趋势是将硬件按钮数量减少到最小限度,因为这被认为更加用户友好(而且因为iPhone只有一个按钮,所以他们复制了这个设计)。其他制造商确实包括菜单按钮,但除非你按下它,否则它是隐藏的(是的,当你不再需要它时它会亮起来。这不是明智的设计,但当手机上所有按钮都关闭时,它看起来更像iPhone)。
为了更好地理解这一点,让我们来看一个例子:用户A
有一个带有菜单键的设备。他正在使用他最喜欢的邮件客户端。配置邮件帐户的选项与常规选项(帮助、关于等)一起放置在溢出菜单中。他想添加第二个帐户,但不知道如何访问此菜单。屏幕上没有信息可以帮助他意识到该怎么做。所以用户A
问他的朋友B
,他也在使用这个邮件客户端。用户B
拥有最新的Nexus N+1 Googlephone,并且能够在操作栏中查看溢出图标,因为他的设备没有硬件菜单键。他向A
展示如何通过打开此菜单来添加第二个帐户。现在用户A
完全困惑了,因为他们在使用相同的应用程序版本。受挫的A
可能会认为问题在于他的手机过时了。B
也感到困惑。
此时,您可能会认为A
和B
都是傻瓜,不知道如何使用智能手机。但与桌面应用程序不同,绝大多数智能手机用户对其设备只知道基础知识。他们之前的手机可能是一个带有简单固件的按键设备。电池已经用尽,他们去商店更换,但是缺货。他们本可以在互联网上订购一部新手机,但价格比购买更新的手机更贵。因此,他们被售出了一个带触摸屏的手机,因为这就是现在的手机。现在他们不得不面对一台配有完整操作系统的小型计算机。更糟的是,手机只提供“快速入门指南”,要获取完整手册,他们必须从互联网上下载PDF文件。你猜怎么着?他们不会这样做。
如果您正在开发移动应用程序,您应该假定用户可能对计算机、操作系统或类似应用程序一无所知。您应该使GUI看起来在各个设备上都相似,以便人们可以学习和记
// For ActionBarSherlock
abs__ic_menu_moreoverflow_normal_holo_dark.png
abs__ic_menu_moreoverflow_normal_holo_light.png
// For ActionBar
ic_menu_moreoverflow_normal_holo_light.png
ic_menu_moreoverflow_normal_holo_dark.png
此外:请将图片复制粘贴到您项目的res文件夹中。您永远不知道未来的ABS版本或下一个ActionBar实现是否会包含它们。
Add SearchView widget for standard search interaction (API 8+ only)
Fix: ShareActionProvider in the split action bar no longer fills the entire screen.
Fix: ShareActionProvider now does file I/O on a background thread.
Fix: Automatically correct ColorDrawable not respecting bounds when used as a stacked background.
Fix: Ensure fragments collection is present before dispatching events.
Fix: XML-defined onClick searches the correct context for the declared method.
Fix: Ensure action mode start/finish callbacks are invoked on the activity for the native action bar.
Fix: Allow tab callbacks to have a fragment transaction instance for any FragmentActivity.
Fix: Ensure CollapsibleActionView callbacks are dispatched in both native and compatbility action bars.
Fix: Remove .ForceOverflow themes. These never should have been included.
theme.xml
中使用它:<style name="MyTheme" parent="@style/Theme.Sherlock.ForceOverflow">
<item name="android:windowBackground">@color/background</item>
<item name="actionBarStyle">@style/Widget.Styled.ActionBar</item>
<item name="android:actionBarStyle">@style/Widget.Styled.ActionBar</item>
</style>
<style name="MyTheme.ForceOverflow">
<item name="absForceOverflow">true</item>
</style>
当为Activity
在manifest.xml
中应用主题时,我使用以下属性:"@style/Theme.SociallyYOU"
另外,如果你一定要强制溢出,你可能也想阅读CommonsWare在这里另一个问题上的想法:https://stackoverflow.com/a/12872537/450534。
注意:话虽如此,如果权衡不是太重要,始终使用最新版本会更好。通过发布我如何强制溢出菜单,我既不建议您使用旧版本,也不推荐这样做。它只是告诉您可能性。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/more"
android:icon="@drawable/overflow"
android:showAsAction="always"
/>
</menu>
private Dialog popupDialog;
private Boolean popupState=false;
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
case R.id.more:
if (!popupState) {
showPop();
}else {
popupDialog.dismiss();
}
default:
return super.onOptionsItemSelected(item);
}
}
private void showPop(){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(ResID, null);
ListView listView = (ListView) view.findViewById(ResID);
listView.setAdapter(yourOwnAdapter);
popupDialog = new Dialog(WifiAuthWireActivity.this);
popupDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
popupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
popupDialog.setContentView(view);
// Calculate ActionBar height
TypedValue tv = new TypedValue();
ActionBar maActionBar=getSupportActionBar();
int actionBarHeight=maActionBar.getHeight();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
WindowManager.LayoutParams wmlp = popupDialog.getWindow().getAttributes();
wmlp.gravity = Gravity.TOP | Gravity.RIGHT;
wmlp.x+=12;
wmlp.y+=actionBarHeight;
popupDialog.getWindow().setAttributes(wmlp);
popupDialog.show();
}
Fragment
中使用onKeyUp
,我想处理硬件菜单键
的点击事件。 - Shajeel Afzal