如何从Android 2.3上的ActionBarSherlock溢出菜单中删除图标?

时间:2013-02-28 08:09:15

标签: android menu icons actionbarsherlock

我有一个使用主题ActionBarSherlock Theme.Sherlock.Light.DarkActionBar的应用。操作栏很暗,我的菜单图标很亮。当我在小布局上运行我的应用程序时,溢出菜单中会显示带有图标的2或3个菜单项。

在Android 3+上,溢出菜单项不会显示其图标,但在Android 2.3及更早版本中,我会看到带有几乎不可见图标的菜单图块,因为图块颜色为白色,图标接近白色。

enter image description here

正如您所看到的,灯光图标在白色背景上是不可见的,但它们必须具有浅色才能在黑暗的操作栏上显示:

enter image description here

在溢出菜单中显示菜单项时,我可以删除图标吗?

5 个答案:

答案 0 :(得分:3)

您可以使用配置限定符。 e.g。

制作一个可绘制的文件夹 / res / drawable-v11 /将所有“light”图标放入其中。

对于较暗的图标使用 / res / drawable / folder。

请务必在两个文件夹中使用相同的文件名。

我希望我理解你的问题,这可能对你有帮助。

但是,如果你想为溢出菜单更改drawables JUST,我认为这是不可能的。此外,因为菜单图标不打算像这样使用。 ActionBarSherlock可能也是因为这样的问题,而不是官方库。

答案 1 :(得分:2)

我也遇到了同样的问题:

有很多方法可以实现这一目标,而不是删除图像:

1)您可以使用相应的可绘制文件夹来放置明暗图像。

2)您还可以通过检查设备版本来更改菜单代码的背景颜色。

如果您的设备不支持溢出菜单,您可以更改菜单的背景颜色,也可以更改菜单文本颜色。

我也遇到了同样的问题并使用以下一个解决了问题:

static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
public View onCreateView(String name, Context context, AttributeSet attrs) {
    if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
        try {
            Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
            Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
            final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

            new Handler().post(new Runnable() {
                public void run() {
                    try {
                        view.setBackgroundColor(Color.BLACK);
                        List<View> children = getAllChildren(view);
                        for(int i = 0; i< children.size(); i++) {
                            View child = children.get(i);
                            if ( child instanceof TextView ) {
                                ((TextView)child).setTextColor(Color.WHITE);
                            }
                        }
                    }
                    catch (Exception e) {
                        Log.i(TAG, "Caught Exception!",e);
                    }

                }
            });
            return view;
        }
        catch (Exception e) {
            Log.i(TAG, "Caught Exception!",e);
        }
    }
    return null;
}       
}

public List<View> getAllChildren(ViewGroup vg) {
ArrayList<View> result = new ArrayList<View>();
for ( int i = 0; i < vg.getChildCount(); i++ ) {
    View child = vg.getChildAt(i);
    if ( child instanceof ViewGroup) {
        result.addAll(getAllChildren((ViewGroup)child));
    }
    else {
        result.add(child);
    }
}
return result;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
LayoutInflater lInflater = getLayoutInflater();
if ( lInflater.getFactory() == null ) {
    lInflater.setFactory(new MenuColorFix());
}
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.myMenu, menu);
}

3)从styles.xml文件中更改背景颜色

<style name="Theme.MyTheme" parent="Theme.Sherlock.ForceOverflow">
    <item name="actionBarStyle">@style/Widget.MyTheme.ActionBar</item>
    <item name="android:actionBarStyle">@style/Widget.MyTheme.ActionBar</item>
</style>

<style name="Widget.MyTheme.ActionBar" parent="Widget.Sherlock.ActionBar">
    <item name="android:background">#ff000000</item>
    <item name="background">#ff000000</item>
</style>

对我来说,所有3个都工作正常

希望,这对你也有用

答案 2 :(得分:0)

OS 2.x很乱,因为选项菜单背景可能是黑色或白色,具体取决于设备,无法确定哪一个。

简单的解决方法是使用适用于Android 2.x&amp;的灰色(#888888)图标。将现代(ICS / JB)图标放在现代设备的v11文件夹中:

drawable      // old school icons
drawable-v11  // modern icons

当然这意味着drawable-mdpi-v11,drawable-hdpi-v11等等。

答案 3 :(得分:0)

为2.x版本添加一整套重复暗图标的简单替代方法可以简单地从可以转到溢出菜单的所有项目中删除图标。例如:

res/menu

<item
    android:id="@+id/menu_send_email"
    android:showAsAction="ifRoom"
    android:title="@string/menu_send_email"/>

res/menu-v11(甚至是res/menu-v9,因为2.3通常有一个黑暗的菜单)

<item
    android:id="@+id/menu_send_email"
    android:icon="@drawable/ic_action_send_email"
    android:showAsAction="ifRoom"
    android:title="@string/menu_send_email"/>

当然,你需要让标题足够短,以便至少在一些较大的屏幕上适应ActionBar,或者解决它们总是进入溢出的事实。

答案 4 :(得分:0)

另一个选项是从onPrepareOptionsMenu中的非操作项中删除图标。

这个想法是使用actionbarsherlock的MenuItemImpl.isActionButton来确定每个项目是否是一个动作项目,如果没有删除图标。这有点棘手,因为onPrepareOptionsMenu被ABS调用(至少)两次 - 这是第一次构建操作栏时,在这种情况下MenuItemImpl.isActionButton尚未设置并且将始终返回false。如果是这种情况,您希望单独留下图标。构建操作栏后,isActionButton方法将对操作栏项返回true,否则返回false。因此,您要删除返回false的图标。这就是我想出的:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        boolean buildingOptionsMenu = false;
        for (int i=0; i<menu.size(); ++i) {
            MenuItemImpl mi = (MenuItemImpl)menu.getItem(i);
            if (mi.isActionButton()) {
                buildingOptionsMenu = true;
                break;
            }
        }

        if (buildingOptionsMenu) {
            for (int i=0; i<menu.size(); ++i) {
                MenuItemImpl mi = (MenuItemImpl)menu.getItem(i);
                if (!mi.isActionButton()) {
                    mi.setIcon(null);
                    mi.setIcon(0);
                }
            }               
        }
    }
    return super.onPrepareOptionsMenu(menu);
}

您需要这两个导入:

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.internal.view.menu.MenuItemImpl;

这适用于ABS 4.3.0,但由于它使用内部库类,因此可能无法与其他版本的库一起使用。