13

I need to change color of the password toggle in TextInputLayout if EditText is focused or not. I've done it this way but it's not working. The color is always equals color light grey (from state focused = false)

layout

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:passwordToggleEnabled="true"
        app:passwordToggleDrawable="@drawable/password_toggle_selector"
        app:passwordToggleTint="@color/color_password_toggle">

    <android.support.design.widget.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>

color_password_toggle

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

password_toggle_selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_eye" android:state_checked="true />
    <item android:drawable="@drawable/ic_eye_off" />

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
druger
  • 141
  • 1
  • 3
  • 9

4 Answers4

12

With the TextInputLayout included in Material Components library the passwordToggleTint attribute (the icon to use for the password input visibility toggle) is deprecated.

Now just use the endIconTint attribute.

<com.google.android.material.textfield.TextInputLayout
    ...
    app:endIconMode="password_toggle"
    android:hint="Password"
    style="@style/FilledBoxEndIconTint">

    <com.google.android.material.textfield.TextInputEditText
         ...
         android:inputType="textPassword"/>

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

with:

  <style name="FilledBoxEndIconTint" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
    <item name="endIconTint">@color/my_selector_color</item>
  </style>

You can use a color or a selector.

enter image description here

You can also use the app:endIconTint attribute in the layout:

 <com.google.android.material.textfield.TextInputLayout
            ...
            app:endIconMode="password_toggle"
            android:hint="Password"
            app:endIconTint="@color/my_selector_color">

The default selector is:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorPrimary" android:state_activated="true"/>
  <item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
  <item android:alpha="0.6" android:color="?attr/colorOnSurface"/>
</selector>
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • 1
    it's not helped me. it works [like that](https://drive.google.com/open?id=1ZkrNmvFpe7N1KxBDmUeIr3NKx4XMnWO9) but i [need so](https://drive.google.com/open?id=11MBzuM4cJ8qOrwCIFq7jRBHMNx7Vjbt-) – druger Aug 31 '19 at 19:03
  • It is the standard component with a standard behavior.Just change the color in the selector but you can't introduce new states. – Gabriele Mariotti Aug 31 '19 at 19:41
10

I used : app:passwordToggleTint="@android:color/black" inside TextInputLayout

ashishdhiman2007
  • 807
  • 2
  • 13
  • 28
7

Create color_password_toggle.xml in res/color directory :

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

And you can remove the custom icon to use the default eye icon :

<android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:passwordToggleEnabled="true"
        app:passwordToggleTint="@color/color_password_toggle">

    <android.support.design.widget.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
Chitrang
  • 5,097
  • 1
  • 35
  • 58
0

It seems that when TextInputEditText gains focus, it does not set TextInputLayout state to state_activated.

However, it is easy to achieve that if you create your own version of TextInputEditText.

class MyTextInputEditText : TextInputEditText {
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context) : super(context)

    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        getTextInputLayout()?.setEndIconActivated(focused)
    }

    //copied from TextInputEditText (why this is private?)
    private fun getTextInputLayout(): TextInputLayout? {
        var parent = parent
        while (parent is View) {
            if (parent is TextInputLayout) {
                return parent
            }
            parent = parent.getParent()
        }
        return null
    }
}

And basically just do what @gabriele-mariotti recommended, create a selector combining android:state_activated, android:state_enabled and android:state_checked for your needs.

I've suggested a change in the Material library, check the PR on GitHub.

rewgoes
  • 656
  • 2
  • 9
  • 23