Search code examples
androidandroid-actionbarandroid-toolbarandroid-theme

Set menu item background color on hover in Android


I have menu items in my app, and I would like to change color of item background, when it is clicked (please see screenshot - item 1 is clicked)

item 1 is clicked

I just want one color here - either light blue, or dark one. However, as you can see, there are two of them on the first item.

Here is my code:

Toolbar in activity:

    <android.support.v7.widget.Toolbar
            xmlns:sothree="http://schemas.android.com/apk/res-auto"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/main_toolbar"
            sothree:theme="@style/MyActionBar"
            android:layout_alignParentTop="true"
            style="@style/toolbarButton">

            ...

        </android.support.v7.widget.Toolbar>

Styles:

    <style name="toolbarButton">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:clickable">true</item>
    </style>
    <style name="MyActionBar"
        parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@color/material_dark_blue</item>
        <item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
        <item name="android:icon">@android:color/transparent</item>
        <item name="android:centerX">@android:integer/config_shortAnimTime</item>
        <item name="windowActionBar">false</item>
    </style>
    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:textColor">@color/material_white</item>
        <item name="android:popupMenuStyle">@style/CustomOverflowBack</item>
        <item name="android:itemTextAppearance">@android:color/white</item>
    </style>

Manifest:

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

Any help is highly appreciated.

UPDATE: Adding CustomOverflowBack:

    <style name="CustomOverflowBack" parent="@android:style/Widget.Holo.Light.ListPopupWindow">
        <item name="android:popupBackground">@drawable/menu_item</item>
    </style>

Menu_item.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listview_background_shape">

    <stroke android:width="1dp" android:color="@color/material_dark_blue" />
    <solid android:color="@color/actionbar_item_bg_color" />

</shape>

Solution

  • Replace this

    <style name="toolbarButton">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:clickable">true</item>
    </style>
    <style name="MyActionBar"
        parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@color/material_dark_blue</item>
        <item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
        <item name="android:icon">@android:color/transparent</item>
        <item name="android:centerX">@android:integer/config_shortAnimTime</item>
        <item name="windowActionBar">false</item>
    </style>
    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:textColor">@color/material_white</item>
        <item name="android:popupMenuStyle">@style/CustomOverflowBack</item>
        <item name="android:itemTextAppearance">@android:color/white</item>
    </style>
    
    <style name="CustomOverflowBack" parent="@android:style/Widget.Holo.Light.ListPopupWindow">
        <item name="android:popupBackground">@drawable/menu_item</item>
    </style>
    

    With this:

    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="actionBarPopupTheme">@style/AppThemeOverlay.Popup</item>
    </style>
    
    <style name="AppThemeOverlay.Popup" parent="ThemeOverlay.AppCompat.Dark">
        <item name="android:colorBackground">popup menu background color</item>
        <item name="colorControlHighlight">selected item color</item>
    </style>
    

    Here's how you use it:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="?colorPrimary"
        android:elevation="4dp"
        app:popupTheme="?actionBarPopupTheme"/>
    

    The above is enough to make it work on API 21 and above.

    I left out your toolbarButton style because it's unrelated to the issue.

    Here are some hints

    <style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
    

    Do not use platform styles for AppCompat widgets. If you used AppCompat style @style/Widget.AppCompat.ActionBar you would have to override virtually none of the attributes.

    <item name="android:background">@color/material_dark_blue</item>
    

    Background in a theme will be applied to any view that does not override it. That's why you see the blue square. android:background is a style attribute, use it on widgets. android:colorBackground is a theme attribute and it's used (among other things) to color the android:popupBackground, which provides the shape of a popup menu.

    <item name="android:textColor">@color/material_white</item>
    

    Text color is again more of a style attribute used on TextViews. Widely used theme attributes are android:textColorPrimary and android:textColorSecondary. Use those instead. android:textColor in a theme may produce unexpected/undesired results.

    <item name="android:itemTextAppearance">@android:color/white</item>
    

    Do NOT put a color resource into a style/text appearance attribute. It will not work or crash or worse produce unexpected results without crashing.