【问题标题】:Check If MenuItem is In ActionBar Overflow检查 MenuItem 是否在 ActionBar 中溢出
【发布时间】:2012-08-17 03:07:28
【问题描述】:

问题:如果 MenuItem(或哪些 MenuItems)在 ActionBar 的溢出菜单中,有没有办法检查代码? 我正在使用 ActionBarSherlock

我需要这个的原因是,如果有空间,我有一堆图标会显示在 ActionBar 中。我有一个全息黑暗主题,所以图标是为了适应它。

当菜单项被放入溢出菜单时,我的问题就出现了。在 Pre-Honeycomb 设备上,这意味着它们将在用户按下菜单按钮时显示。这个菜单的背景与我的 ActionBar 完全相反,我想要一组不同的图标来适应它。

【问题讨论】:

  • 图标不显示在溢出菜单项中。
  • 我知道他们没有。这不是我要问的。我指出我对前蜂窝设备感兴趣(菜单图标确实显示)。
  • 如果我们找到一种方法可以禁用溢出菜单中的 MenuItems 上的图标,以便仅文本出现在旧菜单中,这也会很有帮助。
  • 你应该看看Icon Design Guidelines,会更容易...
  • 我已经看过这个网站很多次了。你能具体说明我应该去哪里吗?

标签: android overflow actionbarsherlock menuitem


【解决方案1】:

我可能已经找到了解决这个问题的方法:在设计指南 (here) 中,有一个表格显示了根据 dip 的宽度显示了多少操作栏项。

基于该表,我编写了以下代码:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem search = menu.findItem(R.id.menu_search);

    // Get width in dp
    DisplayMetrics metrics = new DisplayMetrics();
    Display display = getWindowManager().getDefaultDisplay();
    display.getMetrics(metrics);
    float logicalDensity = metrics.density;
    int dp = (int) (display.getWidth() / logicalDensity + 0.5);

    if (dp < 360) { // only two icons
        search.setIcon(R.drawable.ic_menu_search);  // Show menu icon for pre-3.0 menu
    } else {
        search.setIcon(R.drawable.ic_action_search); // Show action bar icon for action bar
    }

    return true;
}

【讨论】:

    【解决方案2】:

    我发布了一个类似问题的答案,可以解决您的问题,请参阅:

    https://stackoverflow.com/a/18884872/1299562

    基本上您可以使用 onPrepareOptionsMenu 来删除非操作项图标。

    【讨论】:

      【解决方案3】:

      您可以使用反射。将以下代码放入一个类中,然后调用Foo.isInOverflow(yourMenuItem);

      protected static final String SUPPORTCLASS = "android.support.v7.internal.view.menu.MenuItemImpl";
      
      protected static final String NATIVECLASS = "com.android.internal.view.menu.MenuItemImpl";
      
      protected static Method sSupportIsActionButton;
      
      protected static Method sNativeIsActionButton;
      
      static {
          try {
              Class<?> MenuItemImpl = Class.forName(NATIVECLASS);
              sNativeIsActionButton = MenuItemImpl.getDeclaredMethod("isActionButton");
              sNativeIsActionButton.setAccessible(true);
          } catch (Exception ignored) {
          }
          try {
              Class<?> MenuItemImpl = Class.forName(SUPPORTCLASS);
              sSupportIsActionButton = MenuItemImpl.getDeclaredMethod("isActionButton");
              sSupportIsActionButton.setAccessible(true);
          } catch (Exception ignored) {
          }
      }
      
      // --------------------------------------------------------------------------------------------
      
      /**
       * Check if an item is showing (not in the overflow menu).
       * 
       * @param item
       *            the MenuItem.
       * @return {@code true} if the MenuItem is visible on the ActionBar.
       */
      public static boolean isActionButton(MenuItem item) {
          switch (item.getClass().getName()) {
          case SUPPORTCLASS:
              try {
                  return (boolean) sSupportIsActionButton.invoke(item, (Object[]) null);
              } catch (Exception e) {
                  // fall through
              }
          case NATIVECLASS:
              try {
                  return (boolean) sNativeIsActionButton.invoke(item, (Object[]) null);
              } catch (Exception e) {
                  // fall through
              }
          default:
              return true;
          }
      }
      
      /**
       * Check if an item is in the overflow menu.
       * 
       * @param item
       *            the MenuItem
       * @return {@code true} if the MenuItem is in the overflow menu.
       * @see #isActionButton(MenuItem)
       */
      public static boolean isInOverflow(MenuItem item) {
          return !isActionButton(item);
      }
      

      注意:您需要将以下行添加到您的 proguard 配置文件中,以便反射在生产构建中起作用:

      -keep public class android.support.v7.internal.view.menu.** { *; }
      

      【讨论】:

      • 将其更改为与 android.support.v7.internal.view.menu.MenuItemImpl 一起使用,但随后我在 API 10 上获得了 NoSuchMethodException(即使我正在使用具有该方法的 appcompat 版本 22 进行构建)。在 API 22 上运行时,它可以工作,但会给出错误的结果(据说所有操作/工具栏图标都处于溢出状态,即使其中只有一些是...)。
      • @Matthias,我更新了代码。如果您仍有问题或发现问题,请告诉我。
      【解决方案4】:

      如果您使用的是Toolbar,那么您可以在Kotlin 中创建一个简单的扩展或在Java 中创建静态函数,以查看工具栏菜单项是在工具栏上可见还是隐藏在溢出选项菜单中。

      这是一个示例函数及其用法:

      fun Toolbar.isMenuItemOverflowing(@IdRes id: Int): Boolean {
          return this.findViewById<View>(id) == null
      }
      

      将函数与工具栏实例一起使用:-

      toolbar.isMenuItemOverflowing(R.id.action_search)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-06
        • 1970-01-01
        • 1970-01-01
        • 2020-08-15
        • 1970-01-01
        • 2019-01-23
        • 2012-03-09
        • 1970-01-01
        相关资源
        最近更新 更多