检查菜单项是否位于操作栏溢出区域

4
问题:是否有一种方法可以在代码中检查一个MenuItem(或哪些MenuItems)是否在ActionBar的溢出菜单中? 我正在使用ActionBarSherlock
我需要这样做的原因是因为我有一堆图标,如果有空间,它们将显示在ActionBar中。 我使用了深色主题,所以这些图标是为此而制作的。
我的问题在于当菜单项放入溢出菜单中时。 在Pre-Honeycomb设备上,这意味着当用户按下菜单按钮时它们将显示。 这个菜单的背景与我的ActionBar完全相反,我想有一组不同的图标来适应它。

1
图标不显示在溢出菜单项中。 - superfell
我知道他们不会。那不是我的问题。我指出我对Honeycomb之前的设备感兴趣(菜单图标确实显示)。 - Sababado
如果我们找到一种方法,可以禁用溢出菜单中的MenuItem上的图标,这将非常有帮助,这样只有文本会出现在传统菜单中。 - Matthew Runo
你应该查看图标设计指南,这样会更容易… - user1521536
我已经多次浏览了这个网站。你能具体说明我应该看哪里吗? - Sababado
4个回答

3
我可能找到了解决这个问题的方法:在设计指南(这里)中,有一张表格显示了根据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;
}

1

如果您正在使用Toolbar,则可以使用Kotlin创建一个简单的扩展或在Java中静态函数中查找工具栏菜单项是否可见于工具栏或隐藏到溢出选项菜单中。

以下是示例函数及其用法:

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

使用具有工具栏实例的函数:-
toolbar.isMenuItemOverflowing(R.id.action_search)

0
你可以使用反射。将以下代码放入一个类中,然后调用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上运行时,它可以工作,但会给出错误的结果(所有Action/Toolbar图标都被认为在溢出中,即使只有其中一些...)。 - Matthias
@Matthias,我已更新代码。如果您仍然有问题或发现有错误,请告诉我。 - Jared Rummler

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接