如何更改 Android 2.3 的选项菜单背景?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10394016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:33:07  来源:igfitidea点击:

How can I change the Options menu background for Android 2.3?

androidmenubackgroundoptions

提问by SpicyWeenie

I have the same standard options menu, but I want to change the background of the items from white to black. I've seen many postings about how to do it, but those don't work for 2.3.

我有相同的标准选项菜单,但我想将项目的背景从白色更改为黑色。我看过很多关于如何做的帖子,但那些不适用于 2.3。

Does anyone know of a working menu inflater with a custom-colored background compatible with version 2.3?

有谁知道具有与 2.3 版兼容的自定义颜色背景的工作菜单充气器?

**ATTENTION**NO IMAGE PLACEMENT!!! NO CODE FROM OTHER POSTINGS, BECAUSE IVE TRIED THEM ALL HERE!!!

**注意* *无图片放置!!!没有来自其他帖子的代码,因为我在这里都试过了!!!

采纳答案by Kumar Bibek

In an ideal scenario, you shouldn't be doing that. Various devices would have different colors, as they decide. If you really really have to customize the menu item's backgrounds, then, I would suggest don't use it. Instead, create some kind of context menu, which you can fully customize as per your needs.

在理想情况下,您不应该这样做。根据他们的决定,不同的设备会有不同的颜色。如果您真的必须自定义菜单项的背景,那么我建议不要使用它。相反,创建某种上下文菜单,您可以根据需要对其进行完全自定义。

I know its probably not a solution you are asking for, but whatever workarounds you will be be doing for this, it might work for a few device, and would probably be a disaster for others.

我知道这可能不是您要求的解决方案,但是无论您为此采取什么解决方法,它都可能适用于一些设备,而对其他人来说可能是一场灾难。

回答by dira

See if following solution solves your problem....

看看以下解决方案是否能解决您的问题....

AndroidMenifest.xml

AndroidMenifest.xml

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/CustomTheme">

menu/options.xml

菜单/选项.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/option_1" android:title="Android"/>
    <item android:id="@+id/option_2" android:title="iPhone"/>
    <item android:id="@+id/option_3" android:title="iPad"/>
</menu>

styles.xml

样式文件

<resources>
    <style name="CustomTheme" parent="android:Theme">
        <!-- Panel attributes -->
        <!-- <item name="android:panelBackground">@drawable/menu_bg</item> -->
        <item name="android:panelFullBackground">@drawable/menu_full_bg</item> 
            <!--    <item name="android:panelColorBackground">#FF0000</item> -->
    </style>

    <!-- <drawable name="menu_bg">#DDDAAA</drawable> -->
    <drawable name="menu_full_bg">#000FFF</drawable>

</resources>

StackoverflowActivity.java

StackoverflowActivity.java

public class StackoverflowActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options, menu);
        return true;
    }

}

Output

输出

回答by Shankar Agarwal

The below code is working fine 2.3.6(test on device and emulator). It is almost copied & combined from different sites from google search

下面的代码工作正常 2.3.6(在设备和模拟器上测试)。它几乎是从谷歌搜索的不同站点复制和组合的

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    setMenuBackground();
    return super.onCreateOptionsMenu(menu);
}

protected void setMenuBackground() {
    getLayoutInflater().setFactory(new Factory() {
     @Override
                public View onCreateView(final String name, final Context context,
                        final AttributeSet attrs) {

                    if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {

                        try { // Ask our inflater to create the view
                            final LayoutInflater f = getLayoutInflater();
                            final View[] view = new View[1];
                            try {
                                view[0] = f.createView(name, null, attrs);
                            } catch (InflateException e) {
                                hackAndroid23(name, attrs, f, view);
                            }
                            // Kind of apply our own background
                            new Handler().post(new Runnable() {
                                public void run() {
                                    view[0].setBackgroundColor(Color.BLUE);

                                }
                            });
                            return view[0];
                        } catch (InflateException e) {
                        } catch (ClassNotFoundException e) {

                        }
                    }
                    return null;
                }
            });
        }

        static void hackAndroid23(final String name,
                final android.util.AttributeSet attrs, final LayoutInflater f,
                final View[] view) {
            try {
                f.inflate(new XmlPullParser() {
                    @Override
                    public int next() throws XmlPullParserException, IOException {
                        try {
                            view[0] = (TextView) f.createView(name, null, attrs);
                        } catch (InflateException e) {
                        } catch (ClassNotFoundException e) {
                        }
                        throw new XmlPullParserException("exit");
                    }

                    @Override
                    public void defineEntityReplacementText(String entityName,
                            String replacementText)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public int getAttributeCount() {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public String getAttributeName(int index) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getAttributeNamespace(int index) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getAttributePrefix(int index) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getAttributeType(int index) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getAttributeValue(int index) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getAttributeValue(String namespace,
                            String name) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public int getColumnNumber() {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public int getDepth() {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public int getEventType() throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public boolean getFeature(String name) {
                        // TODO Auto-generated method stub
                        return false;
                    }

                    @Override
                    public String getInputEncoding() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public int getLineNumber() {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public String getName() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getNamespace() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getNamespace(String prefix) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public int getNamespaceCount(int depth)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public String getNamespacePrefix(int pos)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getNamespaceUri(int pos)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getPositionDescription() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getPrefix() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public Object getProperty(String name) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public String getText() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public char[] getTextCharacters(
                            int[] holderForStartAndLength) {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public boolean isAttributeDefault(int index) {
                        // TODO Auto-generated method stub
                        return false;
                    }

                    @Override
                    public boolean isEmptyElementTag()
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return false;
                    }

                    @Override
                    public boolean isWhitespace() throws XmlPullParserException {
                        // TODO Auto-generated method stub
                        return false;
                    }

                    @Override
                    public int nextTag() throws XmlPullParserException,
                            IOException {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public String nextText() throws XmlPullParserException,
                            IOException {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public int nextToken() throws XmlPullParserException,
                            IOException {
                        // TODO Auto-generated method stub
                        return 0;
                    }

                    @Override
                    public void require(int type, String namespace, String name)
                            throws XmlPullParserException, IOException {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void setFeature(String name, boolean state)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void setInput(Reader in)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void setInput(InputStream inputStream,
                            String inputEncoding) throws XmlPullParserException {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void setProperty(String name, Object value)
                            throws XmlPullParserException {
                        // TODO Auto-generated method stub

                    }
                }, null, false);
            } catch (InflateException e1) {
                // "exit" ignored
            }
        }

回答by Mehul Joisar

i was searching for the same stuff but when i installed my application in my Samsung galaxy Ywhich is having version 2.3.6. i got black background for optionmenu automatically.although the emulator displays me white background for same menu.i don't know how it is working like that,but i got what i want.so i left it unaltered.
Here is the code:

我正在寻找相同的东西,但是当我在我的三星 Galaxy Y 中安装了我的应用程序时,它的版本是 2.3.6。我自动获得了 optionmenu 的黑色背景。虽然模拟器为我显示了同一个菜单的白色背景。我不知道它是如何工作的,但我得到了我想要的。所以我没有改变它。
这是代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    MenuInflater inflater1 = getMenuInflater();
    inflater1.inflate(R.menu.scfmenu, menu);

    return true;
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.settings:
        Intent i = new Intent(getApplicationContext(), prefsActivity.class);
        startActivity(i);
        break;
    case R.id.logout:
        Intent j = new Intent(getApplicationContext(), LoginActivity.class);
        startActivity(j);
        break;
    }

    return super.onOptionsItemSelected(item);
}

回答by R4j

I found this funny postfrom codeproject. You can custom everything you want: bk color, icon. And you can change the menu style with this:

我从 codeproject 中发现了这篇有趣的帖子。您可以自定义您想要的一切:bk 颜色、图标。您可以通过以下方式更改菜单样式:

  mMenu.setItemsPerLineInLandscapeOrientation(8);
  mMenu.setItemsPerLineInPortraitOrientation(4);

Note: it is a trick to add view look like option menu. Hope this help!

注意:添加视图看起来像选项菜单是一个技巧。希望这有帮助!

回答by Khan

i have used the code as shown below on 2.3.1 version and it works and just call in onCreat method addOptionsMenuHackerInflaterFactory();

我在 2.3.1 版本上使用了如下所示的代码,它可以工作,只需调用 onCreat 方法 addOptionsMenuHackerInflaterFactory();

private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
    menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
    menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    return super.onOptionsItemSelected(item);
}
@SuppressWarnings("rawtypes")
static Class       IconMenuItemView_class = null;
@SuppressWarnings("rawtypes")
static Constructor IconMenuItemView_constructor = null;

// standard signature of constructor expected by inflater of all View classes
@SuppressWarnings("rawtypes")
private static final Class[] standard_inflater_constructor_signature = 
new Class[] { Context.class, AttributeSet.class };

protected void addOptionsMenuHackerInflaterFactory()
{
    final LayoutInflater infl = getLayoutInflater();

    infl.setFactory(new Factory()
    {
        public View onCreateView(final String name, 
                                 final Context context,
                                 final AttributeSet attrs)
        {
            if (!name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView"))
                return null; // use normal inflater

            View view = null;

            // "com.android.internal.view.menu.IconMenuItemView" 
            // - is the name of an internal Java class 
            //   - that exists in Android <= 3.2 and possibly beyond
            //   - that may or may not exist in other Android revs
            // - is the class whose instance we want to modify to set background etc.
            // - is the class we want to instantiate with the standard constructor:
            //     IconMenuItemView(context, attrs)
            // - this is what the LayoutInflater does if we return null
            // - unfortunately we cannot just call:
            //     infl.createView(name, null, attrs);
            //   here because on Android 3.2 (and possibly later):
            //   1. createView() can only be called inside inflate(),
            //      because inflate() sets the context parameter ultimately
            //      passed to the IconMenuItemView constructor's first arg,
            //      storing it in a LayoutInflater instance variable.
            //   2. we are inside inflate(),
            //   3. BUT from a different instance of LayoutInflater (not infl)
            //   4. there is no way to get access to the actual instance being used
            // - so we must do what createView() would have done for us
            //
            if (IconMenuItemView_class == null)
            {
                try
                {
                    IconMenuItemView_class = getClassLoader().loadClass(name);
                }
                catch (ClassNotFoundException e)
                {
                    // this OS does not have IconMenuItemView - fail gracefully
                    return null; // hack failed: use normal inflater
                }
            }
            if (IconMenuItemView_class == null)
                return null; // hack failed: use normal inflater

            if (IconMenuItemView_constructor == null)
            {
                try
                {
                    IconMenuItemView_constructor = 
                    IconMenuItemView_class.getConstructor(standard_inflater_constructor_signature);
                }
                catch (SecurityException e)
                {
                    return null; // hack failed: use normal inflater
                }
                catch (NoSuchMethodException e)
                {
                    return null; // hack failed: use normal inflater
                }
            }
            if (IconMenuItemView_constructor == null)
                return null; // hack failed: use normal inflater

            try
            {
                Object[] args = new Object[] { context, attrs };
                view = (View)(IconMenuItemView_constructor.newInstance(args));
            }
            catch (IllegalArgumentException e)
            {
                return null; // hack failed: use normal inflater
            }
            catch (InstantiationException e)
            {
                return null; // hack failed: use normal inflater
            }
            catch (IllegalAccessException e)
            {
                return null; // hack failed: use normal inflater
            }
            catch (InvocationTargetException e)
            {
                return null; // hack failed: use normal inflater
            }
            if (null == view) // in theory handled above, but be safe... 
                return null; // hack failed: use normal inflater


            // apply our own View settings after we get back to runloop
            // - android will overwrite almost any setting we make now
            final View v = view;
            new Handler().post(new Runnable()
            {
                public void run()
                {
                    v.setBackgroundColor(Color.BLUE);

                    try
                    {
                        // in Android <= 3.2, IconMenuItemView implemented with TextView
                        // guard against possible future change in implementation
                        TextView tv = (TextView)v;
                        tv.setTextColor(Color.RED);
                    }
                    catch (ClassCastException e)
                    {
                        // hack failed: do not set TextView attributes
                    }
                }
            });

            return view;
        }
    });
}

the output for backround blue and textcolor red as shown below enter image description here

背景蓝色和文本颜色红色的输出如下所示 在此处输入图片说明