TextInputLayout 密码切换侦听器

TextInputLayout Password Toggle Listener

我有一个 TextInputLayout 作为密码。我添加了 passwordToggleEnabled=true 来切换密码可见性。 我需要在用户切换密码可见性时捕获事件。我该怎么做。

<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>

TextInputLayout 的来源中,切换按钮的视图类型是 CheckableImageButton。您只需要找到在 TextInputLayout 视图的子视图上递归迭代的视图。然后 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;
}

请参阅 , but in short you can do the following since Material Components v1.1.0 (Kotlin):

textInputLayout.setEndIconOnClickListener {
    // do something here
}

像另一个答案中建议的那样仅设置结束图标点击侦听器是行不通的,因为这样做会删除用于切换 EditText 转换方法的现有侦听器。

所以如果你设置了一个新的监听器,你需要自己改变它:

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.
}

如果您仍在寻找有关 TextInputLayout 密码切换侦听器的完整解决方案,请检查此答案:

    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());
                        }
                    });
                }
            }
        });

    }
}

设置 EndIconOnClickListener 时,需要同时检查 TextInputEditText 文本状态和 TextInputLayout EndIcon Drawable 文件。所以你可以像这样管理这个场景。