TextInputLayout密码切换监听器

4

我有一个用于密码的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>

您可以使用此答案中发布的UI组件:https://dev59.com/vKTia4cB1Zd3GeqP9i7u#51264033 - GaRRaPeTa
4个回答

5
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;
}

如何检查密码是否可见?在这两种情况下,输入类型都为129。 - Nitesh V
在你的onTouchListener中使用一个布尔变量isVisible作为示例,当用户点击切换按钮时,相应地改变变量的值(true或false)。这是我能提出的最好建议。 - Rainmaker
好的,我们可以使用CheckableImageButton.isChecked,但必须添加@SuppressLint("RestrictedApi")。否则会显示错误“CheckableImageButton.ischecked只能从同一库组内调用”。 - Nitesh V

1

如果只设置结束图标的点击监听器,就像另一个答案中提出的那样,是行不通的,因为这样做会删除用于切换 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.
}

这也将播放未/交叉眼睛的动画。 PasswordToggleEndIconDelegate 还会调用 textInputLayout.refreshEndIconDrawableState(),以防您的图标的色调列表具有取决于单击的状态的颜色。 - TreyWurm

1
请检查此答案,如果您仍在寻找有关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文件。因此,您可以像这样管理此场景。

-1

不,这个监听器将替换切换密码可见性的监听器。 - Markus Penguin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接