Saturday, June 18, 2011

How to change the background color of Android options menu

I have been trying my hand at developing apps with Android.  I have had my fair share of leanings.  Today I am going to share my experience around styling the options menu in Android.

What is the options menu?

Options menu is the menu that is shown to the user when the Menu key is pressed on the Android phone.

Lets look at an example, that will make things easier to understand.

The layout file.

The above code shows the following GUI
As you can see from the above screenshot the background color of the Activity is greenish while the default Color of the selected element of the options menu is Orange.

It definitely looks inconsistent and ugly.  This is the reason we need to style the options menu to match the rest of the application theme.

Android platform is highly configurable.  One can change all aspects of look and feel on the android platform.  Hence, when this task was given to me, I thought it would be a 2 min fix.  But unfortunately it took much longer than I expected.

All I wanted to do is change the background selector of the options menu.  Android does not provide a straight forward way to do this.  In fact, it meant writing quiet some code.  I decided to write a post on this, so that other can benefit from my learning's.

So back to the original question.  How do we change the background color of Android options menu?

How do they do it?

Now there is nothing fancy about the above code.  But to change the background color we have to write some fancy code :)

Changing the options menu background color is a 8 step process
  1. Setting the custom LayoutInflater.Factory instance.
  2. Implementing the onCreateView method that will actually set the background selector for the options menu.
  3. In the implementation of onCreateView, check if the view that is to be created is of type com.android.internal.view.menu.IconMenuItemView.  Yes, I know, its an *internal* class!
  4. If the view is of type IconMenuItemView then create the view using the LayoutInflater.
  5. At this point we have an instance of IconMenuItemView but we cannot change the background color of the view directly.  Even if we change the background color at this point, framework updates it again and our changes are overwritten
  6. We have to change the background color after the view has rendered, using the Handler API.
  7. Change the background color in run method of the Runnable instance that we pass to the Handler's post method.
  8. Catch all exceptions that could occur in the entire process.  Notice that, we are using an internal class there are high changes that its behavior could change without any notice.  In fact this approach does not work on Android 2.3.  In this case we have to fallback to the default menu styling.
Yep, I know, it looks like a lot of work and pretty complex too.  Lets look at the code to make things more clear.

The menu_selector is an XML file that choses the background color based on the state of the menu item.  My menu_selector.xml looks like this

The colors.xml file looks like

The comments are embedded in the code. One new methods has been added called setMenuBackground. This method does the job for us!

The screenshots of the styled options menu
 As we can see the Options Menu background color has been changed from Orange to greenish.

That's all folks!

We have successfully changed the background color of Android options men.  But wait a minute, how to change the default text color of the Android options menu?  If this question is bothering you stay tuned, in the next post I am going to explain exactly that!
Have some Fun!