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

前端 未结 6 967
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-15 11:18

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 wo

相关标签:
6条回答
  • 2020-12-15 11:25

    i have used the code as shown below on 2.3.1 version and it works and just call in onCreat method 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

    0 讨论(0)
  • 2020-12-15 11:26

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

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

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

    0 讨论(0)
  • 2020-12-15 11:29

    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.

    0 讨论(0)
  • 2020-12-15 11:38

    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

    @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
                }
            }
    
    0 讨论(0)
  • 2020-12-15 11:40

    i was searching for the same stuff but when i installed my application in my Samsung galaxy Y which 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:

    @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);
    }
    
    0 讨论(0)
  • 2020-12-15 11:46

    See if following solution solves your problem....

    AndroidMenifest.xml

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

    menu/options.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

    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

    0 讨论(0)
提交回复
热议问题