我设法在工具栏的溢出菜单和子菜单中显示图标,但我找不到如何根据它们的位置为图标着色。这是我正在使用的代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar_main, menu);

    // Show icons in overflow menu
    if (menu instanceof MenuBuilder) {
        MenuBuilder m = (MenuBuilder) menu;
        m.setOptionalIconsVisible(true);
    }

    // Change icons color
    changeIconsColor(menu, colorNormal, colorInMenu, false);

    return super.onCreateOptionsMenu(menu);
}

public static void changeIconsColor(Menu menu, int colorNormal, int colorInMenu, boolean isInSubMenu) {
    // Change icons color
    for (int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        Drawable icon = item.getIcon();
        if (icon != null) {
            int color = (((MenuItemImpl) item).requiresActionButton() ? colorNormal : colorInMenu);
            icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
            icon.setAlpha(item.isEnabled() ? 255 : 128);
        }

        if (item.hasSubMenu()) {
            changeIconsColor(item.getSubMenu(), colorNormal, colorInMenu, true);
        }
    }
}
MenuItem.requiresActionButton() 的使用允许知道一个项目是否在 XML 的 never 属性中具有 alwaysshowAsAction 值,但不知道它是否具有 ifRoom 值。因此,如果我想要适当的着色,我不能在项目中使用 ifRoom 值,这是非常严格的。
  • 有没有办法在所有情况下正确着色菜单项?
  • 更重要的是,是否有一种内置的方法可以使用主题或样式为项目着色,从而避免使用这段复杂的代码?即使解决方案不涵盖溢出菜单中的图标,我也想了解它。

  • 如果没有其他方法,我完全可以使用反射。

    最佳答案

    不幸的是,无法使用主题或样式设置菜单项图标颜色的色调。您需要一种方法来检查 MenuItem 是否在 ActionBar 或溢出菜单中可见。 native 和支持 MenuItemImpl 类都有一个方法,但它们要么被限制在库中,要么被隐藏。这需要反射(reflection)。您可以使用以下方法检查菜单项是否可见,然后设置颜色过滤器:

    public static boolean isActionButton(@NonNull MenuItem item) {
      if (item instanceof MenuItemImpl) {
        return ((MenuItemImpl) item).isActionButton();
      } else {
        // Not using the support library. This is a native MenuItem. Reflection is needed.
        try {
          Method m = item.getClass().getDeclaredMethod("isActionButton");
          if (!m.isAccessible()) m.setAccessible(true);
          return (boolean) m.invoke(item);
        } catch (Exception e) {
          return false;
        }
      }
    }
    

    您还需要等到菜单膨胀后再为项目着色。为此,您可以获取对 ActionBar 的引用,并在绘制 MenuItem 后为 ActionBar 着色。

    例子:
    @Override public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.menu_main, menu);
    
      int id = getResources().getIdentifier("action_bar", "id", "android");
      ViewGroup actionBar;
      if (id != 0) {
        actionBar = (ViewGroup) findViewById(id);
      } else {
        // You must be using a custom Toolbar. Use the toolbar view instead.
        // actionBar = yourToolbar
      }
    
      actionBar.post(new Runnable() {
        @Override public void run() {
          // Add code to tint menu items here
        }
      });
    
      return super.onCreateOptionsMenu(menu);
    }
    

    这是我写的一个类来帮助着色菜单项图标:https://gist.github.com/jaredrummler/7816b13fcd5fe1ac61cb0173a1878d4f

    关于android - 溢出菜单和子菜单中的色调菜单图标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50780057/

    10-11 22:31
    查看更多