在ActionBarSherlock强制溢出菜单

我希望在ICS设备(2.3 – 2.1)上使用4.0+溢出菜单。 我使用HoloEverywhere与ActionBarSherlock。

我尝试了以下解决scheme:

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。 您可以按照其发布历史logging获取下载列表: http : //actionbarsherlock.com/download.html

我个人仍然使用ABS版本4.1.0,因为我目前不想在我的应用程序中进行辅助更改。 我也在我的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> 

manifest.xmlActivity应用一个主题时,我使用这个属性: "@style/Theme.SociallyYOU"

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

注意:这就是说,使用最新版本总是更好,如果权衡不是很重要的话。 发布如何强制溢出菜单,我既不build议你使用旧版本,也不build议。 它只是告诉你可能性。

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

  1. 为了强制Android 3.x(honeycomb)和upper的菜单可见性,你需要使用这个 hack + add检查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
    • 将原件replace为:

      公共静态布尔reserveOverflow(上下文上下文){返回true; }

    这将强制菜单显示…

    • 但是当点击菜单button菜单popup不显示。 为了达到这个目的,我们需要在你的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版本devise溢出操作栏菜单。

正如Siddharth Lele所指出的那样 ,它在最后的ABS版本中已被删除,以便与实际的Action Bar相同。 所以乍一看放弃显示这个菜单是最好的select。

但是,在我看来,在Android的Action Bar中,一些设备的屏幕上显示的溢出菜单并没有显示给别人,这是一个很大的devise缺陷。 原因如下:

在具有硬件菜单键的设备中,菜单不会显示在操作栏中。 最近的设备趋势是将硬件button的数量减less到最低限度,因为它被认为是更加用户友好的(因为iPhone只有一个button,所以他们复制这个devise)。 其他制造商也包括菜单button,但是除非你按压它,否则它是隐藏的(是的,当你不再需要灯光时它会亮起来,而不是一个明智的devise,但是当所有的buttonclosures时,电话看起来更加iphonish)。

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

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

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

后键出现类似的情况。 一些设备可能有一个硬件返回键,新的通常不会。 但是,只要我们可以回到我们的应用程序,我们总是在操作栏中显示那个箭头状的button,对吧? 是的,我知道一个button在“导航树”中导航,而另一个则在“回到时间”,但这也是另一个devise缺陷:对于中等用户,后退就是回来。 他在屏幕上有这个button,他也可以使用硬件,但这是可选的。 溢出菜单也应该这样做。

所以如果你想(像我一样)这是一个重要的button,不要放弃。 提供一个常规的主选项菜单,并填入相应的子菜单。 使其成为一个动作button,并为其指定一个描述性的图标,甚至像“菜单”的文字说明。 您也可以模仿溢出菜单图标,只需使用以下其中一种绘图:

  // 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的下一个实现将包含它们。

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

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