Search code examples
androidandroid-edittextmaterial-designandroid-themeandroid-styles

Cannot set colorControlNormal and android:textColor in style


I am trying to style a material EditText view:

<style name="AppTheme.EditText" parent="@style/Widget.AppCompat.EditText">
    <item name="android:textColor">@color/white</item>
    <item name="android:textColorHint">#8AFFFFFF</item>

    <item name="colorControlNormal">@color/white</item>
    <item name="colorControlActivated">@color/white</item>
    <item name="colorControlHighlight">@color/white</item>
</style>

Then I apply the style on my theme:

<style name="AppTheme">
    <item name="editTextStyle">@style/AppTheme.EditText</item>
</style>

And apply theme to activity:

  <activity
        android:name=".MyActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="stateAlwaysHidden"
        android:theme="@style/AppTheme">

However this is not changing the underline color.

I know that I can change the accentColor to change the underline color, but I don't want to do that as I need my accent color to be different for some of the other controls.

Can I style the control underline color like this?


Solution

  • Reason it is not working: colorControlNormal is an attr of the theme while android:textColor is a style attribute. To change colorControlNormal, you have to override a Theme, to change android:textColor value, you have to override a style. There is no attributes named colorControlNormal in @style/Widget.AppCompat.EditText or any parents of it. Therefore, you are overriding nothing when doing this:

    <style name="AppTheme.EditText" parent="@style/Widget.AppCompat.EditText">
        <item name="colorControlNormal">@color/white</item>
    </style>
    

    Solution: To actually change the value of colorControlNormal, you have to change it in a theme. To do that without changing the activity's theme, you can:

    1/ Create a ThemeOverlay with only the theme attributes that you wish to change:

    <style name="AppTheme.EditText"> 
        <item name="colorControlNormal">@color/white</item>
    </style>
    

    2/ Use it only in the your EditText view:

    <EditText
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.EditText"
    />
    

    What is actually happening here is that the View's theme attributes (if exists) will be used. The activity's theme will be used as fallback.

    You can always change colorControlNormal of the activity's theme to affect the whole activity.