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

13
我有一个应用程序,使用主题Theme.Sherlock.Light.DarkActionBarActionBarSherlock。动作栏是黑色的,我的菜单图标是浅色的。当我在小布局上运行我的应用程序时,2或3个带图标的菜单项会显示在溢出菜单中。
在Android 3+上,溢出菜单项将不显示它们的图标,但在Android 2.3及更早版本上,我看到菜单瓷砖几乎看不见的图标,因为瓷砖颜色是白色,图标接近白色。

enter image description here

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

enter image description here

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


2
你可以发一张图片吗? - Korniltsev Anatoly
我建议您将此问题发布在ABS问题页面上,因为这似乎是一个非常严重的错误。我的意思是,没有人想使用Light.DarkActionBar。以下是问题页面的链接: https://github.com/JakeWharton/ActionBarSherlock/issues - DominicM
你是否添加了额外的样式或配置?我期望溢出菜单项以垂直菜单的形式显示,颜色与操作栏相同,因此是一个带有单列的深色菜单。 - flup
5个回答

3
您可以使用配置限定符。例如,
创建一个drawable文件夹/res/drawable-v11/,并将所有“浅色”图标放入其中。
对于较暗的图标,请使用/res/drawable/文件夹。
请确保在两个文件夹中使用相同的文件名。
希望我已经理解了您的问题,并且这可能会帮助您。
但是,如果您想仅更改溢出菜单的可绘制项,我认为这是不可能的。同时因为菜单图标不打算像这样使用。 ActionBarSherlock 可能也因为类似的问题,不是官方库。

ActionBarSherlock在v11之前的设备上添加了一个操作栏,但他仍然希望在这些设备上使用浅色图标,以便与深色操作栏形成对比。 - Travis

2
我也遇到了同样的问题:
有许多方法可以实现这个目标,而不必删除图像:
1)您可以使用相应的drawable文件夹来放置浅色和深色图像。
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>

对我来说,这三个都运行良好。

希望这对你也有效。


1
另一种选项是在 onPrepareOptionsMenu 中删除非动作项中的图标。想法是使用 actionbarsherlock 的 MenuItemImpl.isActionButton 来确定每个项目是否为动作项,如果不是,则删除图标。这有点棘手,因为 ABS 至少会调用一次 onPrepareOptionsMenu,即在构建操作栏时第一次调用,此时 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中有效,但由于它使用内部库类,所以可能无法与库的其他版本配合使用。

0
一个简单的替代方案是,对于2.x版本,可以将所有可以进入溢出菜单的项目中的图标删除,而不是添加一整套重复的暗色图标。例如: < p > < code > 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在一些较大的屏幕上,或者接受它们总是进入溢出菜单的事实。


0

由于选项菜单的背景颜色在设备上可能是黑色或白色且没有确切的方法可以知道,因此OS 2.x很混乱。

简单的解决方法是对于Android 2.x及以下版本使用灰色(#888888)图标,并将您现代化(ICS/JB)的图标放入一个v11文件夹以适用于现代设备:

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

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

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