How to change Menu Item text Color of holo theme in Android?
Asked Answered
S

2

9

I am using Theme.Holo in my app.

I have customized my theme using following Style.xml

<style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
    <item name="android:actionBarStyle">@style/CustomActivityTheme.ActionBar</item>
    <item name="android:actionMenuTextColor">#000000</item>
    <item name="android:divider">@drawable/action_bar_div</item>
    <item name="android:actionOverflowButtonStyle">@style/MyActionButtonOverflow</item>
    <item name="android:popupMenuStyle">@style/MyPopupMenu</item>
    <item name="android:itemBackground">@drawable/menu_item_background_fill</item>

    <item name="android:itemTextAppearance">@style/myCustomMenuTextApearance</item>
</style>

<style name="myCustomMenuTextApearance" parent="@android:style/TextAppearance.Widget.TextView.PopupMenu">
    <item name="android:textColor">#404040</item>
</style>

<style name="CustomActivityTheme.ActionBar.OverFlow" parent="@android:style/TextAppearance">
    <item name="android:textColor">#404040</item>
    <item name="android:textSize">18sp</item>
</style>
<style name="CustomButton"> 
     <item name="android:background">@drawable/button_selector</item>
</style>
 <style name="CustomProgressButton">
     <item name="android:background">@drawable/custom_progress_button</item>
</style>
<style name="CustomProfileButton">
     <item name="android:background">@drawable/custom_profile_button</item>
</style>
<style name="CustomSharingButton">
     <item name="android:background">@drawable/custom_sharing_button</item>
</style>
<style name="CustomListBlue">
     <item name="android:background">@drawable/custom_listblue</item>
</style>

<style name="MyPopupMenu" parent="android:style/Widget.Holo.Light.ListPopupWindow">
    <!-- <item name="android:background">#B2B2B2</item> -->
    <item name="android:popupBackground">#B2B2B2</item>

</style>

<style name="MyActionButtonOverflow" parent="android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/overflow</item>
</style>

<style name="CustomActivityTheme.ActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
    <item name="android:background">@drawable/actionbar_bg</item>
    <item name="android:titleTextStyle">@style/CustomActivityTheme.ActionBar.Text</item>
    <item name="android:subtitleTextStyle">@style/CustomActivityTheme.ActionBar.Text</item>
    <!-- <item name="android:actionOverflowButtonStyle">@drawable/overflow.png</item> -->
</style>

<style name="CustomActivityTheme.ActionBar.Text" parent="@android:style/TextAppearance">
    <item name="android:textColor">#000000</item>
    <item name="android:textSize">16sp</item>
</style>

<style name="activated" parent="android:Theme.Holo">
    <item name="android:background">?android:attr/activatedBackgroundIndicator</item>
</style>

<!-- style for removing the floating dialog -->
<style name="CustomDialogTheme">
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowNoTitle">true</item>
</style>

<!-- style for transparent image resource  activity -->

<style name="Theme.Transparent" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item>
</style>

<!-- Animations for a non-full-screen window or activity. -->
<style name="MyAnimation.Window" parent="@android:style/Animation.Dialog">
    <item name="android:windowEnterAnimation">@anim/grow_from_middle</item>
    <item name="android:windowExitAnimation">@anim/shrink_to_middle</item>
</style>

<!-- style for transparent audio and video resource  activity -->

<style name="Theme.Transparent_Player" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:windowAnimationStyle">@style/MyPlayerAnimation.Window</item>
</style>

<!-- Animations for a non-full-screen window or activity. -->
<style name="MyPlayerAnimation.Window" parent="@android:style/Animation.Dialog">
    <item name="android:windowEnterAnimation">@anim/grow_from_action_bar</item>
    <item name="android:windowExitAnimation">@anim/shrink_to_action_bar</item>
</style>

I am getting below output in 10 inch device

enter image description here

and in 4.7 inch device, it is showing output(with white text color instead if #404040 color code)

enter image description here

Here, I am able to set the background color but, menu item text color is not changed in 4.7 inch device

in 4.7 inch device, i am not having overflow menu icon, I am opening this menu by pressing menu button.

How to set the text color same as 10 inch device?

Thanx in advance!!!

My menu layout code is:

<item
    android:id="@+id/home"
    android:title="@string/home"/>
<item
    android:id="@+id/viewer"
    android:title="@string/viewer"/>
<item
    android:id="@+id/quiz"
    android:title="@string/quiz"/>
<item
    android:id="@+id/results"
    android:title="@string/results"/>
<item
    android:id="@+id/chat"
    android:title="@string/chat"/>
<item
    android:id="@+id/settings"
    android:title="@string/settings"/>
<item
    android:id="@+id/intro"
    android:title="@string/intro"/>
<item
    android:id="@+id/lookitup"
    android:title="@string/lookitup"/>
<item
    android:id="@+id/standing"
    android:title="@string/standing"/>
<item
    android:id="@+id/sharing"
    android:title="@string/sharing"/>
<item
    android:id="@+id/advance"
    android:title="@string/advance"/>
<item
    android:id="@+id/reset"
    android:title="@string/reset"/>

<item
    android:id="@+id/refresh"
    android:title="@string/refresh"/>

<item
    android:id="@+id/sync_now"
    android:title="@string/sync_now"/>

<item
    android:id="@+id/sync_info"
    android:title="@string/sync_info"/>

<item
    android:id="@+id/menuIconInfo"
    android:icon="@drawable/info_light_on_dark"
    android:showAsAction="always"/>

<item
    android:id="@+id/menuIconAudio"
    android:icon="@drawable/audio_light_on_dark"
    android:showAsAction="always"/>
<item
    android:id="@+id/menuIconVideo"
    android:icon="@drawable/video_light_on_dark"
    android:showAsAction="always"/>

<item
    android:id="@+id/menuIconLearn"
    android:icon="@drawable/ic_menu_learn"
    android:showAsAction="always"/>
<item
    android:id="@+id/menuIconIntro"
    android:icon="@drawable/intro_pane"
    android:showAsAction="always"/>
<item
    android:id="@+id/menuIconLookItUp"
    android:icon="@drawable/look_it_up"
    android:showAsAction="always"/>
<item
    android:id="@+id/menuIconRecall"
    android:icon="@drawable/ic_menu_recall"
    android:showAsAction="always"/>

Sebastian answered 4/2, 2013 at 5:12 Comment(14)
Try to set the theme as for your text as @android:style/Theme.BlackMontemontefiascone
It is showing the same result :(Sebastian
Please post your menu layout code.Montemontefiascone
I haven't pecified background in meny layoutSebastian
Instead of specifying background and color in menu layout, i have specified it in my style.xml by using following code: <item name="android:popupMenuStyle">@style/MyPopupMenu</item> <item name="android:itemBackground">@drawable/menu_item_background_fill</item> <item name="android:itemTextAppearance">@style/myCustomMenuTextApearance</item>Sebastian
Have you set the style of your myCustomMenuTextApearance as <style name="myCustomMenuTextApearance" parent="@android:style/Theme.Black"> <item name="android:textColor">#404040</item> </style> ? Please change the style of your parent property as i have set.Montemontefiascone
let us continue this discussion in chatSebastian
@AkbariDipali did you finally succeeded? I'm trying to do the same, but I can't event change the menu item background as you appear you have done. I opened a question where I ask about it, feel free to answer, even with only the solution about editing the background, upvote is guaranteed with that :PPat
@domenicop yes, the answer that I have given below worked for me like a charm! I tried a lot to change background and textcolor by using style.xml. But the only thing I was able to do is changing the background(you can see "MyPopupMenu" "MyActionButtonOverflow" style for background change in above question). But to change textcolor, I had to use the solution provided in the answer below. Give it a try once. Hope, it will work for you also.Sebastian
@AkbariDipali I'm trying to change the selector with no success via theme. I tried the answer below (overriding the childView background) with no success. Apparently getView is never called with the name com.android.internal.view.menu.ListMenuItemView on ICS. There is no view that contains the word Menu. Could you please double check if you actually posted the working code? Which android version are you applying it on?Pat
@AkbariDipali It's a little messy, and I had to change some things to got it working, that's why I'm asking ^^Pat
@domenicop if you are using icon menu then you should use "com.android.internal.view.menu.IconMenuItemView". Can you please debug the code and check the attribute? I had tried so many options and finally after debugging the solution worked for meSebastian
@AkbariDipali I made the onCreateView method spit out all the name(s) it is called for, and as you can see here, none of them is that class (and none of them contains the work Menu either!) Tried with the IconMenuItemView but nothing changes. Better continue this in a chat, if you will :)Pat
@AkbariDipali Can you tell me which android version you're using this workaround?Pat
S
3

I have solved by changing the background color by code of menu by checking the device version.

If device doen't support overflow menu, the, you can change the background color of menu as well as you can also change menu text color using following one:

static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
public View onCreateView(String name, Context context, AttributeSet attrs) {
    if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
        try {
            Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
            Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
            final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

            new Handler().post(new Runnable() {
                public void run() {
                    try {
                        view.setBackgroundColor(Color.GRAY);
                        List<View> children = getAllChildren(view);
                        for(int i = 0; i< children.size(); i++) {
                            View child = children.get(i);
                            if ( child instanceof TextView ) {
                                ((TextView)child).setTextColor(Color.BLACK);
                            }
                        }
                    }
                    catch (Exception e) {
                        Log.i(TAG, "Caught Exception!",e);
                    }

                }
            });
            return view;
        }
        catch (Exception e) {
            Log.i(TAG, "Caught Exception!",e);
        }
    }
    return null;
}       
}

public List<View> getAllChildren(ViewGroup vg) {
ArrayList<View> result = new ArrayList<View>();
for ( int i = 0; i < vg.getChildCount(); i++ ) {
    View child = vg.getChildAt(i);
    if ( child instanceof ViewGroup) {
        result.addAll(getAllChildren((ViewGroup)child));
    }
    else {
        result.add(child);
    }
}
return result;
}

//and in onCreateContextMenu, placed following code

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
LayoutInflater lInflater = getLayoutInflater();
if ( lInflater.getFactory() == null ) {
    lInflater.setFactory(new MenuColorFix());
}
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.myMenu, menu);
}
Sebastian answered 18/5, 2013 at 5:34 Comment(0)
C
9

You should be able to change the color of the text easily by using SpannableString instead of String - no need for dirty workarounds ;-)

SpannableString s = new SpannableString("My red MenuItem");
s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
item.setTitle(s);
Chanukah answered 25/9, 2013 at 15:12 Comment(1)
Works fine for me, do this in onPrepareOptionsMenu().Magnifico
S
3

I have solved by changing the background color by code of menu by checking the device version.

If device doen't support overflow menu, the, you can change the background color of menu as well as you can also change menu text color using following one:

static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
public View onCreateView(String name, Context context, AttributeSet attrs) {
    if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
        try {
            Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
            Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
            final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

            new Handler().post(new Runnable() {
                public void run() {
                    try {
                        view.setBackgroundColor(Color.GRAY);
                        List<View> children = getAllChildren(view);
                        for(int i = 0; i< children.size(); i++) {
                            View child = children.get(i);
                            if ( child instanceof TextView ) {
                                ((TextView)child).setTextColor(Color.BLACK);
                            }
                        }
                    }
                    catch (Exception e) {
                        Log.i(TAG, "Caught Exception!",e);
                    }

                }
            });
            return view;
        }
        catch (Exception e) {
            Log.i(TAG, "Caught Exception!",e);
        }
    }
    return null;
}       
}

public List<View> getAllChildren(ViewGroup vg) {
ArrayList<View> result = new ArrayList<View>();
for ( int i = 0; i < vg.getChildCount(); i++ ) {
    View child = vg.getChildAt(i);
    if ( child instanceof ViewGroup) {
        result.addAll(getAllChildren((ViewGroup)child));
    }
    else {
        result.add(child);
    }
}
return result;
}

//and in onCreateContextMenu, placed following code

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
LayoutInflater lInflater = getLayoutInflater();
if ( lInflater.getFactory() == null ) {
    lInflater.setFactory(new MenuColorFix());
}
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.myMenu, menu);
}
Sebastian answered 18/5, 2013 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.