Search code examples
androidcheckboxmaterial-designandroid-theme

Cannot get Material Design CheckBox to use styling


I am trying to add two CheckBox views to a feedback Fragment in my current app, which is using the AppCompat library (v7:22.2.1) . The API range for this app is 16-current (22). My manifest is set up with the following theme definition:

android:theme="@style/AppTheme"

which is defined as such in my styles.xml file:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="AppTheme.FacebookFlatButton">
        <item name="android:background">@drawable/facebook_flat_button</item>
        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
        <item name="android:textColor">@android:color/white</item>
    </style>

    <style name="AppTheme.TwitterFlatButton">
        <item name="android:background">@drawable/twitter_flat_button</item>
        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
        <item name="android:textColor">@android:color/white</item>
    </style>

</resources>

The problem is my CheckBox (and I also notice my EditText) views don't default to a proper color such that they are viewable when checked. Here is a screenshot of the Preview in Android Studio and my emulator side-by-side:

Android Studio and Emulator

No matter what combination of style items I put in this style from other SO articles such as this one, the colors don't change in the emulator or on a device, but they are updating in the Preview. I have also tried various tweaks of the parent theme to my custom theme, but nothing seems to matter.

I have tried this in a Nexus 5 (API 19) and a Nexus 6 (API 22) emulator, and it also does the same thing on my Nexus 6 device.

I'm not defining much at all custom here, but I still feel like I'm missing some small critical piece of information here. What am I missing?


Solution

  • OK, after much research and testing, I have a solution that works both for my CheckBox and EditText controls.

    The (bad) assumption on my part was that one theme could take care of AppCompat and Material Design, which is not true. Basically, for AppCompat (< API 21), you have to define your styles with names without the android: prefix, such as this for the CheckBox and EditText:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <!-- Base application theme -->
        <style name="AppTheme" parent="Theme.AppCompat.Light">
            <!-- Customize your theme here. -->
        </style> 
    
        <style name="AppTheme.EditText" parent="Widget.AppCompat.EditText">
            <item name="colorControlNormal">@color/almanac_red_dark</item>
            <item name="colorControlActivated">@color/almanac_red_light</item>
            <item name="colorControlHighlight">@color/almanac_red_light</item>
        </style>
    
        <style name="AppTheme.CheckBox">
            <item name="colorAccent">@color/almanac_red_dark</item>
        </style>
    
        <style name="AppTheme.FlatButton">
            <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
            <item name="android:textColor">@android:color/white</item>
        </style>
    
        <style name="AppTheme.FacebookFlatButton" parent="AppTheme.FlatButton">
            <item name="android:background">@drawable/facebook_flat_button</item>
        </style>
    
        <style name="AppTheme.TwitterFlatButton" parent="AppTheme.FlatButton">
            <item name="android:background">@drawable/twitter_flat_button</item>
        </style>
    
    </resources>
    

    But you have to have another version of the style for Material Design versions (> API 21) in the values-v21 directory (with the Material Design parent theme), with the android: prefix:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="@android:style/Theme.Material.Light">
            <!-- Customize your theme here. -->
        </style>
    
        <style name="AppTheme.EditText">
            <item name="android:colorControlNormal">@color/almanac_red_dark</item>
            <item name="android:colorControlActivated">@color/almanac_red_light</item>
            <item name="android:colorControlHighlight">@color/almanac_red_light</item>
        </style>
    
        <style name="AppTheme.CheckBox">
            <item name="android:colorAccent">@color/almanac_red_dark</item>
        </style>
    
    </resources>
    

    I have tried on the Nexus 4 (API 16), Nexus 5 (API 19) and Nexus 6 (API 22) emulators and my physical Nexus 6 device and everything looks as I expect.