Reputation: 391
I have a TextInputLayout for password. I have added passwordToggleEnabled=true to toggle the password visibility. I need to capture the event when user toggles password visibility. How can I do this.
<android.support.design.widget.TextInputLayout
android:id="@+id/password_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_new_password"
android:inputType="textPassword"/>
</android.support.design.widget.TextInputLayout>
Upvotes: 4
Views: 5267
Reputation: 643
Please check this answer, if you are still looking for a complete solution about TextInputLayout Password Toggle Listener:
public class SampleActivity extends AppCompatActivity {
TextInputLayout password_input_layout;
TextInputEditText password_edit_text;
//textInputLayoutEndIconPressed will be tracked, EndIcon is pressed and toggled or not
private boolean textInputLayoutEndIconPressed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInputLayoutEndIconPressed = false;
password_input_layout = (TextInputLayout) findViewById(R.id.password_input_layout);
password_edit_text = (TextInputEditText) findViewById(R.id.password_edit_text);
password_input_layout.setEndIconOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!textInputLayoutEndIconPressed)
textInputLayoutEndIconPressed = true;
else
textInputLayoutEndIconPressed = false;
if(textInputLayoutEndIconPressed){
runOnUiThread(new Runnable() {
@Override
public void run() {
//Changing Drawable file
password_input_layout.setEndIconDrawable(getResources().getDrawable(R.drawable.ic_visibility_on));
//Changing TextInputEditText password text to open
password_edit_text.setTransformationMethod(null);
}
});
}else{
runOnUiThread(new Runnable() {
@Override
public void run() {
//Changing Drawable file
password_input_layout.setEndIconDrawable(getResources().getDrawable(R.drawable.ic_visibility_off));
//Changing TextInputEditText password text to hide
password_edit_text.setTransformationMethod(new PasswordTransformationMethod());
}
});
}
}
});
}
}
When you set a EndIconOnClickListener, then you need to check both TextInputEditText text status and TextInputLayout EndIcon Drawable file. So you can manage this scenario like this.
Upvotes: 1
Reputation: 7121
Setting only the end icon click listener like proposed in another answer won't work, because doing so will remove the existing listener which is used to toggle the EditText
transformation method.
So if you set a new listener, you need to change it yourself:
textInputLayout.setEndIconOnClickListener {
// Toggle the EditText transformation method from nothing to password or vice versa.
// Selection is lost in the process so make sure to restore it.
val editText = textInputLayout.editText
val oldSelection = editText.selectionEnd
val hidePassword = editText.transformationMethod !is PasswordTransformationMethod
passwordEdt.transformationMethod = PasswordTransformationMethod.getInstance().takeIf { hidePassword }
if (oldSelection >= 0) {
passwordEdt.setSelection(oldSelection)
}
// Do your own stuff here.
}
Upvotes: 2
Reputation: 5770
Please see my answer here, but in short you can do the following since Material Components v1.1.0 (Kotlin):
textInputLayout.setEndIconOnClickListener {
// do something here
}
Upvotes: -1
Reputation: 11120
In the source of the TextInputLayout
the type of the view of the toggle button is CheckableImageButton
. You just need to find the view iterating recursively over children of the TextInputLayout
View. And then setOnTouchListener
.
View togglePasswordButton = findTogglePasswordButton(mTextInputLayoutView);
if (togglePasswordButton != null) {
togglePasswordButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// implementation
return false;
}
});
}
private View findTogglePasswordButton(ViewGroup viewGroup) {
int childCount = viewGroup.getChildCount();
for (int ind = 0; ind < childCount; ind++) {
View child = viewGroup.getChildAt(ind);
if (child instanceof ViewGroup) {
View togglePasswordButton = findTogglePasswordButton((ViewGroup) child);
if (togglePasswordButton != null) {
return togglePasswordButton;
}
} else if (child instanceof CheckableImageButton) {
return child;
}
}
return null;
}
Upvotes: 5