17

I'm placing a TextInputEditText widget onto a white background. When the fragment first loads, the widget does not have focus. The border around the widget is white (or almost white), so it is invisible on a white background. Here is a screenshot of that widget, drawn on a black background for contrast:

As soon as I tap on the widget, the border becomes that of my primary color, which is exactly what I want. Here is a similar screenshot after the widget is activated.

I'm trying to control these colors through a style, and I've tried everything that I can think of, but I cannot figure out how to adjust that color. Here is my style (feel free to laugh at the various attempts):

<style name="MyTextInputLayout" parent="Base.Widget.MaterialComponents.TextInputLayout">
    <item name="android:colorBackground">@android:color/black</item>
    <item name="android:textColorHint">@color/colorPrimary</item>
    <item name="android:paddingStart">16dp</item>
    <item name="android:paddingEnd">16dp</item>
    <item name="android:colorControlActivated">@android:color/black</item>
    <item name="android:colorControlNormal">@android:color/black</item>
    <item name="android:colorControlHighlight">@android:color/black</item>
    <item name="android:backgroundTint">@android:color/black</item>
    <item name="android:colorAccent">@android:color/black</item>
</style>

<style name="MyTextInputEditText" parent="ThemeOverlay.MaterialComponents.TextInputEditText">
    <item name="android:textColor">@android:color/black</item>
    <item name="android:colorBackground">@android:color/black</item>
    <item name="android:colorControlActivated">@android:color/black</item>
    <item name="android:colorControlNormal">@android:color/black</item>
    <item name="android:colorControlHighlight">@android:color/black</item>
    <item name="android:backgroundTint">@android:color/black</item>
    <item name="android:colorAccent">@android:color/black</item>
</style>

And finally, the xml of the layout in case it is helpful:

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:layout_marginBottom="16dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    style="@style/MyTextInputLayout">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/reg_username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/username"
        style="@style/MyTextInputEditText"/>

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

How can I change this border color when the widget is not active (i.e. does not have focus)?

letsintegreat
  • 3,328
  • 4
  • 18
  • 39
AndroidDev
  • 20,466
  • 42
  • 148
  • 239

5 Answers5

26

I solved this in two main steps:

  1. First problem I had was that the parent style for my TextInputLayout style needed to be changed to Widget.MaterialComponents.TextInputLayout.OutlinedBox.

  2. Once I figured that out, I traced through the Android xml for that style and got to a file called mtrl_box_stroke_color.xml. This is a selector where the three colors for the standard TextInputLayout border are declared. That file looks like this:

So I copied that and created my own file in the res/color folder that I called edit_text_box_border.xml. I modified the three colors to suit my purposes, ultimately coming up with this:

<?xml version="1.0" encoding="utf-8"?>
<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="@color/colorPrimary" android:state_hovered="true"/>
    <item android:alpha="0.12" android:color="@color/colorPrimary" android:state_enabled="false"/>
    <item android:alpha="0.38" android:color="@color/colorPrimary"/>
</selector>

Then, back in my style, I had to get rid of my many color attempts and add an item for boxStrokeColor that pointed to this file. Here are both styles:

<style name="MyTextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
        <item name="android:textColorHint">@color/colorPrimary</item>
        <item name="android:paddingStart">16dp</item>
        <item name="android:paddingEnd">16dp</item>
        <item name="boxStrokeColor">@color/edit_text_box_border</item>
    </style>

    <style name="MyTextInputEditText" parent="ThemeOverlay.MaterialComponents.TextInputEditText.OutlinedBox.Dense">
        <item name="android:textColor">@android:color/black</item>
    </style>

Now, when I run the app, I start out with this:

enter image description here

Which then turns into this when I tap on it:

enter image description here

That's what I was going for, so problem solved. Hope this helps someone.

AndroidDev
  • 20,466
  • 42
  • 148
  • 239
9

1.

<com.google.android.material.textfield.TextInputLayout
 ...
 style="@style/Widget.MaterialComponents.TextInputLayout.OutlineBox"
 app:boxStrokeColor = "@android:color/holo_purple"  
 //border color when in active status
 ...

2. add the following in colors.xml file

<color name="mtrl_textinput_default_box_stroke_color">#00ff00</color> //border color when in inactive status

navylover
  • 12,383
  • 5
  • 28
  • 41
1

Add

        app:boxStrokeColor="@color/black"
        app:hintTextColor="@color/black"

to your XML file. I tried all the color options. You can replace the "@color/black" with any color HEX code. Also write app:color and android will show you all the color options, there are many color fields that can be changed, like the error field which we can set to red to indicate the user has entered Invalid Data.

Pratik
  • 11
  • 1
0

In case you need to change the outline color dynamically (for automatic field validation, for example) you can use the following hack:

Set

app:errorTextColor="@color/colorAccepted"
app:errorIconTint="@color/colorAccepted"

for TextInputLayout in xml.

Then in code:

text_input_layout.errorIconDrawable = null to remove the error icon

and text_input_layout.error = " " to enable the coloring or text_input_layout.error = null to disable it.

This way TextInputLayout takes more space. To resolve this you can customize the errorTextAppearance by defining your own style:

<style name="ErrorTextStyle" parent="TextAppearance.MaterialComponents.Caption">
        <item name="android:textSize">0sp</item>
</style>

Note: That's clearly a hack rather than a proper solution.

Paktalin
  • 236
  • 4
  • 16
-1

I use this:

<style name="TextInputLayoutTheme" parent="TextAppearance.AppCompat">
    <item name="android:textColorHint">@color/secondaryTextLight</item>
    <item name="android:backgroundTint" tools:targetApi="lollipop">@color/colorAccent</item>
    <item name="android:textColor">@color/white</item>
    <item name="colorControlActivated">@color/colorAccent</item>
</style>

and in the xml:

<com.google.android.material.textfield.TextInputEditText
                style="@style/TextInputLayoutTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
Mahdi Moqadasi
  • 2,029
  • 4
  • 26
  • 52