【问题标题】:How to remove icons from an ActionBarSherlock's overflow menu on Android 2.3?如何从 Android 2.3 上的 ActionBarSherlock 溢出菜单中删除图标?
【发布时间】:2013-02-14 08:19:13
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你能不能拍张照片?
  • @KorniltsevAnatoly 完成
  • 我建议您将其发布在 ABS 问题页面上,因为这似乎是一个非常糟糕的错误。我的意思是,没有人愿意使用 Light.DarkActionBar。这是问题页面的链接:github.com/JakeWharton/ActionBarSherlock/issues
  • 您是否添加了自己的额外样式或配置?我希望溢出菜单项显示在与操作栏颜色相同的垂直菜单中,因此是一个带有单列的深色菜单。

标签: android menu icons actionbarsherlock


【解决方案1】:

另一个选项是从 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,但由于它使用内部库类,它可能不适用于其他版本的库。

【讨论】:

    【解决方案2】:

    为 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,或者接受它们总是进入溢出的事实。

    【讨论】:

      【解决方案3】:

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

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

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

      当然是指drawable-mdpi-v11、drawable-hdpi-v11等等。

      【讨论】:

        【解决方案4】:

        我也遇到了同样的问题:

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

        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>
        

        对我来说,这三个都很好

        希望,这对你也有用

        【讨论】:

          【解决方案5】:

          您可以使用配置限定符。 例如

          制作一个可绘制的文件夹 /res/drawable-v11/ 把所有的“光”图标放进去。

          对于较暗的图标,请使用 /res/drawable/ 文件夹。

          确保在两个文件夹中使用相同的文件名。

          我希望我已经理解了您的问题,这可能对您有所帮助。

          但是,如果您只想为溢出菜单更改可绘制对象,我认为这是不可能的。也因为菜单图标不打算那样使用。 ActionBarSherlock 可能也是因为这样的问题,不是官方库。

          【讨论】:

          • ActionBarSherlock 在 v11 之前的设备上添加了一个操作栏,他仍然希望在这些设备上使用浅色图标,以便与深色操作栏形成对比。
          猜你喜欢
          • 2016-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多