ActionBarSherlock中强制溢出菜单

我想在预ICS设备(2.3 – 2.1)上使用4.0+溢出菜单。 我正在使用带ActionBarSherlock的HoloEverywhere。

我尝试了以下解决方案:

ActionBarSherlock&HoloEverywhere – 强制溢出?

但它不起作用,因为absForceOverflow不存在。 是在最新版本中删除了什么? 我已经检查了ABS和HE库项目的R文件,并且该字段根本不存在。

我的应用程序的主题设置为@style/Holo.Theme.Sherlock.Light ,这是我尝试inheritance的主题,并将absForceOverflow参数设置为true

如果您使用的是4.2.0版,那么.ForceOverflow主题实际上已被删除。

来源: 版本4.2.0更改日志

更改日志的摘录:

 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. 

如果您绝对需要强制溢出,则需要下载早期版本的ABS。 您可以在此处获取其发布历史记录的下载列表: http : //actionbarsherlock.com/download.html

我个人仍然使用ABS版本4.1.0,因为我目前不想在我的应用程序中进行辅助更改。 我也在我的theme.xml使用它:

   

manifest.xmlActivity应用主题时,我使用它作为属性: "@style/Theme.SociallyYOU"

同样,如果你必须绝对强制溢出,你可能还想在另一个问题中阅读CommonsWare的想法: https : //stackoverflow.com/a/12872537/450534 。

注意:话虽如此,如果权衡不重要,最好使用最新版本。 通过发布我强制溢出菜单的方式,我既不建议您使用旧版本,也不建议使用旧版本。 它只是告诉你可能性。

从ActionbarSherlock 4.2开始,我们失去了管理溢出菜单可见性的能力。 要使其工作,您需要结合两种方法:

  1. 要强制Android 3.x(蜂窝)和鞋面的菜单可见性,您需要使用此 hack + add check 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 
  2. 预蜂窝设备的打开菜单:

    • 打开ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java ,转到方法reserveOverflow
    • 用以下内容替换原件:

      public static boolean reserveOverflow(Context context){return true; }

    这会强制菜单显示……

    • 但是当点击菜单按钮菜单popup窗口没有显示时。 为此,我们需要在您的活动类中覆盖它:

       @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版本中删除,以便与实际的Action Bar相同。 因此,乍一看放弃显示此菜单是最佳选择。

然而,在我看来,Android屏幕中显示某些设备的溢出菜单而不显示其他设备是一个很大的设计缺陷。 原因如下:

在具有硬件菜单键的设备中,菜单不会显示在操作栏中。 最近设备的趋势是将硬件按钮的数量减少到最小,因为它被认为更加用户友好(并且因为iphone没有按钮,所以他们复制了这个设计)。 其他制造商确实包括菜单按钮,但它是隐藏的,除非你按下它(是的,当你不再需要灯时,它会亮起。不是明智的设计,但是当所有按钮都关闭时,手机看起来更加iphonish)。

为了更好地理解这一点的含义,让我们看一个例子: 用户A有一个带菜单键的设备。 他正在使用他最喜欢的邮件客户端。 配置邮件帐户的选项放在溢出菜单中,以及常用选项(帮助,关于等)。 他想添加第二个帐户,但他没有关于如何进入此菜单的线索。 屏幕上没有任何信息可以帮助他意识到该怎么做。 所以用户A问他的朋友B ,他也在使用这个邮件客户端。 用户B拥有最新的Nexus N + 1 Googlephone,并且他能够在操作栏中查看溢出图标,因为他的设备没有运行硬件菜单键。 他显示了A如何通过打开此菜单添加第二个帐户。 用户A现在完全感到困惑,因为他们使用相同的应用程序版本。 沮丧, A可能会认为问题在于他的手机太老了。 B也很困惑。

此时你可能会认为AB都是无法理解如何使用智能手机的傻瓜。 但与桌面应用程序不同,绝大多数智能手机用户不了解其设备的基本知识。 他们以前的手机可能是一个简单固件的键盘设备。 电池坏了,他们去商店替换,但它缺货了。 他们本可以在互联网上订购一台,但它比购买新手机更贵。 所以他们卖了一部支持触摸屏的手机,因为这就是现在的手机。 现在,他们必须面对一台拥有完整操作系统的小型计算机。 更糟糕的是,手机只有一个“快速入门指南”,要获得完整的手册,他们必须从互联网上下载pdf。 你猜怎么了? 他们不会。

如果您正在开发移动应用程序,您应该假设用户可能不了解有关计算机,操作系统或类似应用程序的事情。 您应该使GUI在各种设备上看起来相似,以便人们可以学习并记住如何使用它。 不要责怪Action Bar设计师:如果像AB这样的用户不知道如何进入选项菜单, 那么首先是你的错 。 这就是为什么你应该包括一个始终可见的选项屏幕的方法。

后退键会发生类似的事情。 某些设备可能具有HW后备密钥,较新的设备通常不具备。 但是每当我们回到我们的应用程序时,我们总是在Action Bar中显示箭头状的按钮,对吧? 是的,我知道一个按钮在“导航树”中导航,而另一个按钮“回到过去”,但这也是另一个设计缺陷:对于普通用户,后面只是回来了。 他在屏幕上有这个按钮,他也可以使用HW,但这是可选的。 应该使用溢出菜单完成相同的操作。

所以如果你认为(像我一样)这是一个重要的按钮,不要放弃。 提供常规主选项菜单,并使用相关子菜单填充它。 将其设为操作按钮并为其指定描述性图标,甚至是“MENU”等文本描述。 您还可以模仿溢出菜单图标,只需使用以下其中一个drawable:

  // 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 

此外:将图像复制粘贴到项目资源文件夹中。 您永远不会知道ABS的未来版本或ActionBar的下一个实现是否会包含它们。

我发现Exterminator13的答案在某些Android设备上不起作用(我认为总数很小),但为了适应尽可能多的设备,我使用对话框并使用一个菜单与android:showAsAction =“always”作为溢出菜单按钮。毕竟,actionbarsherlock的溢出菜单的效果是通过它的来源实现的,所以如果它不那么麻烦,为什么不实现我们自己的效果。 如果你懂中文,你也可以看我的博客 。

     

 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(); }