Search code examples
androidmaterial-designandroid-themeandroid-stylesandroid-textinputlayout

Outlined Edit Text stroke color


I'm trying to style a TextInputLayout:

<style name="AppTheme.TextInputLayout.OutlinedBox" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
    <item name="boxStrokeColor">@color/text_input_layout_outlined_box_stroke</item>
    <item name="hintTextColor">@color/text_input_layout_outlined_box_stroke</item>
</style>

And that's the color selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/green_2" android:state_focused="true" />
    <item android:color="@color/green_2" android:state_hovered="true" />
    <item android:color="@color/green_2" android:state_enabled="false" />
    <item android:color="@color/green_2" />
</selector>

And that's my View:

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:hint="@string/surname">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</com.google.android.material.textfield.TextInputLayout>

Why this works as expected applying to the view:

style="@style/AppTheme.TextInputLayout.OutlinedBox"

And theme is not working:

android:theme="@style/AppTheme.TextInputLayout.OutlinedBox"

I'm not getting the differences between these two...

EDIT: maybe I've found this to avoid repeating for each view:

<item name="textInputStyle">@style/AppTheme.TextInputLayout.OutlinedBox</item>

Solution

  • You can define a style:

    <style name="AppTheme.TextInputLayout.OutlinedBox" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
        <item name="boxStrokeColor">@color/text_input_layout_outlined_box_stroke</item>
        <item name="hintTextColor">@color/text_input_layout_outlined_box_stroke</item>
    </style>
    

    and apply it to a view with:

    <com.google.android.material.textfield.TextInputLayout
       style="@style/AppTheme.TextInputLayout.OutlinedBox"
       ..>
    

    At the same time you can define:

      <style name="textInputPrimaryColor" parent="">
        <item name="colorPrimary">@color/.....</item>
      </style>
    

    and then use it with the android:theme attribute:

    <com.google.android.material.textfield.TextInputLayout
       style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
       android:theme="@style/textInputPrimaryColor"
       ..>
    

    In this way you can modify the theme attributes for that view and any child views, which is useful for overriding theme color palettes in a specific portion of your interface.

    More info here.

    In this way you are overriding the colorPrimary attribute in the style Widget.MaterialComponents.TextInputLayout.OutlinedBox.

    For example it is the default selector used by the boxStrokeColor.

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:color="?attr/colorPrimary" android:state_focused="true"/>
      <item android:alpha="0.87" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
      <item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
      <item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
    </selector>
    

    Using the android:theme="@style/textInputPrimaryColor" you can are changing the colorPrimary for this view without extending the style.

    You can achieve the same behavior using the materialThemeOverlay attribute in your style:

      <style name="My.OutlinedBox" parent="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
        <item name="materialThemeOverlay">@style/ThemeOverlay.My.OutlinedBox</item>
      </style>
    

    with:

      <style name="ThemeOverlay.My.OutlinedBox" parent="ThemeOverlay.MaterialComponents.TextInputEditText.OutlinedBox">
        <item name="colorPrimary">@color/......</item>
      </style>
    

    and then apply it to your view:

    <com.google.android.material.textfield.TextInputLayout
       style="@style/My.OutlinedBox"
       ..>
    

    I want all my items with style OutlinedBox to have the box green colored"? I'd like to avoid repeating theme and style for every view...I mean a "global" style that inherit from AppTheme, which is already applied to the whole application in the manifest

    Currently there isn't an attribute to define a style only for the TextInputLayout with an OutlinedBox style.
    You can only assign a global style for all TextInputLayout views in your app using the textInputStyle attribute in your app theme:

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
       ...
       <item name="textInputStyle">@style/My.OutlinedBox</item>
    </style>
    

    Note: it requires the version 1.1.0 of the Material Components Library.