Search code examples
androidandroid-edittextandroid-textinputlayoutmaterial-componentsmaterial-components-android

Overriding editTextStyle doesn't work with latest Material Components base style


In an app of mine, I'm using the Theme.MaterialComponents.Light.NoActionBar as a base style. In this style, which I call AppTheme, I'm trying to override editTextStyle to provide a custom style for com.google.android.material.textfield.TextInputEditText (according to the source code, it uses R.attr.editTextStyle as a default style).

This is my current theme, related to the TIEditText and TILayout:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    [ primary and secondary colors, OnColors, etc.]
    <item name="editTextStyle">@style/AppTheme.TextInputEditText</item>
    <item name="textInputStyle">@style/AppTheme.TextInputLayout</item>

    [ Custom attribute for testing, defined in attrs.xml ]
    <item name="textInputEditTextStyle">@style/AppTheme.TextInputEditText</item>
</style>

For some reason, even though I set editTextStyle, if I use it in code, it does not get applied:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/tilFirstName"
    style="?attr/textInputStyle"
    android:hint="@string/label_firstname"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/firstName"
        style="?attr/editTextStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text="@={viewModel.firstName}" />
</com.google.android.material.textfield.TextInputLayout>

However if I replace the style of firstName with ?attr/textInputEditTextStyle, it works.

Why can't I override editTextStyle in the default theme? What the hell is going on?

Target SDK is 28, minSDK is 21, Material library version is 1.1.0-alpha06


Solution

  • For some reason, even though I set editTextStyle, if I use it in code, it does not get applied

    It happens because the default styles of the TextInputLayout override the editTextStyle using the materialThemeOverlay attribute.

    For example the Widget.MaterialComponents.TextInputLayout.FilledBox has this default style:

    <style name="Widget.MaterialComponents.TextInputLayout.FilledBox" parent="Base.Widget.MaterialComponents.TextInputLayout">
        <item name="materialThemeOverlay">
           @style/ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox
        </item>
        ....
    </style>
    <style name="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
        <item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.FilledBox</item>
    </style>