android - 在溢出菜单和子菜单中为菜单图标着色
问题描述
我设法在工具栏的溢出菜单和子菜单中显示图标,但我找不到如何根据它们的位置为图标着色。这是我正在使用的代码:
@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()
允许知道项目是否具有值never
或在 XMLalways
中的属性中,但不能知道它是否具有值。因此,如果我想要适当的着色,我不能使用项目中的值,这是非常严格的。showAsAction
ifRoom
ifRoom
有没有办法在所有情况下正确着色菜单项?
更重要的是,是否有一种内置的方法可以用主题或样式为项目着色,从而使我免于使用这段复杂的代码?即使解决方案不包括溢出菜单中的图标,我也想知道它。
如果没有其他方法,我完全可以使用反射。
解决方案
不幸的是,无法使用主题或样式设置菜单项图标颜色的色调。您需要一种方法来检查 是否在溢出菜单MenuItem
中或中可见。ActionBar
本机类和支持MenuItemImpl
类都有一个方法,但它们要么被限制在库中,要么被隐藏。这需要反思。您可以使用以下方法检查菜单项是否可见,然后设置颜色过滤器:
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
推荐阅读
- javascript - jquery没有按名称捕获输入选择器
- javascript - setTimeout 立即执行,而不是函数调用中传递的时间
- python - 如何使用 FFT 从图像中去除重复模式
- gem5 - 链接 X86/marshal 文件时的 LTO 编译问题
- parameters - 我可以以某种方式将 TInput/TOutput 页面作为 Inno Setup 中的一个参数传递给函数吗?
- python - 优化具有二进制变量的对称 MIP 的 Gurobi 模型 (PuLP)
- python - 提交表单的修改字段时出错
- flutter - Flutter 只读取部分 JSON
- css - CSS flexbox 样式来填充元素的宽度和高度
- unicode - 为什么 Unicode 有多个平面?