Adneal's answer is great and I was using it until recently. But then I wanted my app to make use of material design and thus Theme.AppCompat.* style and android.support.v7.widget.Toolbar.
Yes, it stopped working and I was trying to fix it by setting Your.Theme's parent to @style/Widget.AppCompat.ActionButton.Overflow. It worked by propertly setting contentDescription but then it failed when casting to ImageButton. It turned out in latest (version 23) android.support.v7class OverflowMenuButton extends from AppCompatImageView. Changing casting class was enought to make it work with Toolbar on Nexus 5 running Lollipop.
Then I ran it on Galaxy S4 with KitKat and no matter what I tried I couldn't set overflow's contentDescription to my custom value. But in AppCompat styles I found it already has default value:
<item name="android:contentDescription">@string/abc_action_menu_overflow_description</item>
So why not use it? Also by Hannes idea (in comments) I implemented listener, to get rid of some random time for delay in postDelayed. And as overflow icon is already in AppCompat library, then I would use it as well - I am applying color filter, so I don't need any icon resource on my own.
My code based on Adneal's work with Android Lollipop improvements:
public static void setOverflowButtonColor(final Activity activity) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
AppCompatImageView overflow=(AppCompatImageView) outViews.get(0);
overflow.setColorFilter(Color.CYAN);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
and as per another StackOverflow answer:
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
}
else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
of course instead of Color.CYAN you can use your own color - activity.getResources().getColor(R.color.black);
EDIT:
Added support for latest AppCompat library (23), which uses AppCompatImageView
For AppCompat 22 you should cast overflow button to TintImageView