4

I'm trying to set the background of the menu pane to be opaque. After a lot of searching and trying out things I can almost get it working by setting 'panelFullBackground', however, I get the unwanted result of losing the top edge of the menu pane along with its shadow effect. I'm guessing that by just setting the color I'm losing additional styles associated with 'panelFullBackground'.

I've set my application to have a custom style. The style inherits from Theme.Light. In my style I'm setting 'panelFullBackground' to a custom color as follows:

In stylex.xml:

<item name="android:panelFullBackground">@color/custom_theme_color</item>

In colors.xml

   <color name="custom_theme_color">#ff00ffff</color>

I've tried using panelColorForeground|Background but they do not achieve what I want.

It should be mentioned that I tried to use the setMenuBackground approach suggested elsewhere to no avail.

Thanks in advance.

PJL
  • 18,735
  • 17
  • 71
  • 68

4 Answers4

0

Try this simple tutorial Android-Menus-My-Way i found on Codeproject, may found useful to you

Antarix
  • 665
  • 1
  • 10
  • 29
0

As Suggested by Louis Semprini here::

@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.BLACK);

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

        return view;
    }
});
}

To use this code, call addOptionsMenuHackerInflaterFactory() ONCE from your activity onCreate() or your activity onCreateOptionsMenu().

The Code works perfect ! Hope this helps !!

Community
  • 1
  • 1
Name is Nilay
  • 2,743
  • 4
  • 35
  • 77
0

You can value from @color to @drawable like below which worked for me:

<style name="MyTheme" parent="@android:style/Theme.Holo.Light">

    <!-- Menu Style -->
    <item name="android:panelBackground">@drawable/blue_background</item>

</style>
Pradip Kharbuja
  • 3,442
  • 6
  • 29
  • 50
0

You can change the background of android menu options. It will look only in the default manner. If you want to change the look and feel of them, consider building a custom view for menu.

mudit
  • 25,306
  • 32
  • 90
  • 132