22

I use a TextInputLayout, I would want to programmatically set the hint text color and the floating label color if the input field is mandatory. Before moving to TextInputLayout I used to set the hint text color programmatically using the following

textField.setHintTextColor(Color.RED);

Can someone guide me on how to set the hint text color and the floating label color programmatically for a TextInputLayout.

In the screenshot attached i would want the hint text Address 1 to be in red when not focused and the on focus the floating label Address 1 should be in red.

enter image description here

S.A.Norton Stanley
  • 1,833
  • 3
  • 23
  • 37
  • Add an onFocusChangeListener to the edit text and change the hint colour, the onFocusChangeListener gives a boolean value in it's parameters which is true if the edit text has focus and false when focus is taken out of it. Set the hintTextColor accordingly. – Shashank Udupa Feb 28 '16 at 14:18
  • I have not try but I think this should work for you: InputTextLayout.getEditText().setHintTextColor(Color.RED); – Stanojkovic Feb 28 '16 at 14:19
  • @Stanojkovic Tried this it does not work. – S.A.Norton Stanley Feb 28 '16 at 14:40
  • You can add a **`OnFocusChangeListener`** to these **TextFields**.I don't know if it works. – wngxao Feb 28 '16 at 14:13

8 Answers8

21

I changed focused color with reflection. Here's the snippet it may help someone.

private void setUpperHintColor(int color) {
    try {
        Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
        field.setAccessible(true);
        int[][] states = new int[][]{
                new int[]{}
        };
        int[] colors = new int[]{
                color
        };
        ColorStateList myList = new ColorStateList(states, colors);
        field.set(textInputLayout, myList);

        Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
        method.setAccessible(true);
        method.invoke(textInputLayout, true);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

EDIT 2018-08-01:

If you are using design library v28.0.0 and later, fields had changed from mDefaultTextColorto defaultHintTextColor and from mFocusedTextColor to focusedTextColor.

Check decompiled class for other fields.

JerabekJakub
  • 5,268
  • 4
  • 26
  • 33
alexandrius
  • 1,097
  • 1
  • 10
  • 21
  • 1
    You are awesome man. If you knew how much time I spent to find a solusion! – Hesam Feb 07 '18 at 23:36
  • Thanks but I don't really suggest using this method. – alexandrius Feb 08 '18 at 08:37
  • 1
    I know why you don't suggest but I didn't find a normal way using Android methods to change the color dynamically. Do you have any idea how to do that? Thanks – Hesam Feb 08 '18 at 18:20
  • I would suggest creating your own InputLayout. That's what I did – alexandrius Feb 09 '18 at 19:15
  • This solution doesn't work anymore, with API 28 I'm getting java.lang.NoSuchFieldException: No field mDefaultTextColor in class Landroid/support/design/widget/TextInputLayout; – JerabekJakub Aug 01 '18 at 08:16
  • 2
    Please take note, since 09 January 2019, the following changes have been made - `mFocusedTextColor` changed to `focusedTextColor` `mDefaultTextColor` changed to `defaultHintTextColor` `mCollapsingTextHelper` changed to `collapsingTextHelper` `mCollapsedTypeface` changed to `collapsedTypeface` – Cheok Yan Cheng Jan 09 '19 at 07:33
  • This is a dangerous method because whenever android changes, it will throw and exception - and even though caught, the UI will not behave the way you would like. – Jeff Padgett Mar 26 '20 at 22:21
17

With the Material Components library you can use:

In the layout:

<com.google.android.material.textfield.TextInputLayout
    app:hintTextColor="@color/mycolor"
    android:textColorHint="@color/text_input_hint_selector"
    .../>

in a style:

<style name="..." parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
    <!-- The color of the label when it is collapsed and the text field is active -->
    <item name="hintTextColor">?attr/colorPrimary</item>
    <!-- The color of the label in all other text field states (such as resting and disabled) -->
    <item name="android:textColorHint">@color/mtrl_indicator_text_color</item>
</style>

in the code:

// Sets the text color used by the hint in both the collapsed and expanded states
textInputLayout.setDefaultHintTextColor(...);

//Sets the collapsed hint text color
textInputLayout.setHintTextColor(....);
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
7

Please, take a good look at the documentation here: TextInputLayout Methods

There is a method :

setHintTextAppearance(int resId)

Which takes a resource id that could be a style resource!

I would try this and see how it goes!

I hope it helps you!

Pavel Poley
  • 5,307
  • 4
  • 35
  • 66
Eenvincible
  • 5,641
  • 2
  • 27
  • 46
  • Tried the following if(isMandatory()){ textInputLayout.setHintTextAppearance(Color.RED); } still no luck. isMandatory() is a method which indicates if the field is mandatory :-( – S.A.Norton Stanley Feb 28 '16 at 14:54
  • 1
    Try this answer http://stackoverflow.com/questions/33709066/how-to-set-textinputlayout-error-message-colour?rq=1 – Eenvincible Feb 28 '16 at 15:00
  • That somehow did not work for me as well. I tried this textInputLayout.setErrorEnabled(true); textInputLayout.setError(" ");. This displays the floating label in red now, however no hint text appears. Will post this as an answer for completeness. – S.A.Norton Stanley Feb 28 '16 at 15:22
  • Alright! I am glad you got something closer to what you wanted – Eenvincible Feb 28 '16 at 15:24
  • Expected Resource Type Style and not Color. Make sure you read the Methods before you post your own description about it – Bhavik Mehta Jul 10 '18 at 07:28
4

Normally TextInputLayout hint text color comes from app's colorAccent.

But if you want to change then you can use style for that.

<android.support.design.widget.TextInputLayout
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:theme="@style/TextLabel">
 </android.support.design.widget.TextInputLayout>

@style

<style name="TextLabel" parent="TextAppearance.AppCompat">
    <!-- Hint color and label color in FALSE state -->
    <item name="android:textColorHint">@color/Color Name</item> 
    <item name="android:textSize">20sp</item>
    <!-- Label color in TRUE state and bar color FALSE and TRUE State -->
    <item name="colorAccent">@color/Color Name</item>
    <item name="colorControlNormal">@color/Color Name</item>
    <item name="colorControlActivated">@color/Color Name</item>
 </style>

But if you want to add red color then how you can differentiate with error color means basic standard error have Red color.

textField.setHintTextColor(Color.RED); Can someone guide me on how to set the hint text color and the floating label color programmatically for a TextInputLayout.

setHintTextColor works for API 23+

ViramP
  • 1,659
  • 11
  • 11
3

For Changing the both Focused Color and Default Text Color for TextInput Layout

private void setInputTextLayoutColor(int color, TextInputLayout textInputLayout) {
    try {
        Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
        field.setAccessible(true);
        int[][] states = new int[][]{
                new int[]{}
        };
        int[] colors = new int[]{
                color
        };
        ColorStateList myList = new ColorStateList(states, colors);
        field.set(textInputLayout, myList);

        Field fDefaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor");
        fDefaultTextColor.setAccessible(true);
        fDefaultTextColor.set(textInputLayout, myList);

        Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
        method.setAccessible(true);
        method.invoke(textInputLayout, true);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

EDIT : To Change AppCompactEditText line color

You need to set the backgroundTintList (or supportBackgroundTintList) on the EditText to an instance of ColorStateList containing only the color you wish to change the tint to. An easy way to do this in a backwards-compatible way looks like this:

ColorStateList colorStateList = ColorStateList.valueOf(color)
editText.setSupportBackgroundTintList(colorStateList)

This will give the EditText the desired underline color.

Naveen Kumar M
  • 7,497
  • 7
  • 60
  • 74
  • 1
    Thanks for providing `mDefaultTextColor`. It is required, if we decide the change the float text color, even when EditText is disabled. – Cheok Yan Cheng Jul 04 '18 at 12:57
1

I was facing the quite same problem but with mutable hints and colored symbol. I'm made this trick with data binding and Spannable in this way.

 <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/ti_last_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="4dp"
                android:layout_marginEnd="8dp"
                app:boxStrokeWidth="0dp"
                app:boxStrokeWidthFocused="0dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/et_last_name"
                    style="@style/EditText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:onFocusChangeListener="@{viewModel.onFocusChangeListener(@string/last_name)}"
                    tools:hint="@string/last_name" />
</com.google.android.material.textfield.TextInputLayout>

viewModel.onFocusChangeListener defined in this way

    fun onFocusChangeListener(hint: String) =
        OnFocusChangeListener { view, isFocused ->
            (view.parent.parent as TextInputLayout).apply {
                val editText = (view as TextInputEditText)
                if (isFocused) {
                    this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
                    editText.hint = ""
                    this.hint = hint
                } else {
                    if (!editText.text.isNullOrBlank()) {
                        this.defaultHintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
                        editText.hint = ""
                        this.hint = hint
                    } else {
                        this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.hint_color))
                        val builder = SpannableStringBuilder()
                        builder.append(hint)
                        val start = builder.length
                        val end = start + 1
                        builder.append("\u2981")
                        builder.setSpan(
                            ForegroundColorSpan(Color.RED),
                            start,
                            end,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                        builder.setSpan(
                            SuperscriptSpan(),
                            start,
                            end,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                        editText.hint = builder
                        this.hint = ""
                    }
                }
            }

        }

It's allow to use different hints and colors for focused/not focused states and has colored span.

this.getColor() it's just extension

 fun View.getColor(color: Int): Int {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        this.context.resources.getColor(color, context.theme)
    } else {
        this.context.resources.getColor(color)
    }
Stanislav Bondar
  • 6,056
  • 2
  • 34
  • 46
0

Let me share my experience on this. I also tried all solutions given in every related question to this one. i.e. Change hint color of child widget to TextInputLayout

I am glad to share the answer to this question with a little detail.

All we need to know is:-

  1. Adding below line to style of either TextInputLayout or its child widget, is not much a help.

    <item name="android:textColorHint">@color/white</item>

    as it will use colorAccent whenever the focus is received/granted to editable widget.

  2. The actual answer to this problem is to add that style line in Application's style tag, by which it will set hint color when that or any editable area is not in focus. (That is the point we miss everytime).

Please let me know if we have other information on this.

Thanks!

Harpreet
  • 2,990
  • 3
  • 38
  • 52
-5

I was able to get the FloatingLabel in red using the following

textInputLayout.setErrorEnabled(true);
textInputLayout.setError(" ");

enter image description here

S.A.Norton Stanley
  • 1,833
  • 3
  • 23
  • 37