[Android] TextInputLayout变更密码的默认隐藏行为

参考自 com.google.android.material.textfield.TextInputLayout

TextInputLayout

Google为开发者提供了一个功能多样的输入框,包括密码输入时的交互行为为开发者提供了极大的帮助。但大家在使用密码输入模式时会遇到一个疑问:

TextInputLayout在启用密码输入模式时,在输入框的右边会出现一个用于显隐密码明文的小眼睛,但这个小眼睛默认是不掩盖密码明文的,同时也找不到对应的接口去设置它是否默认掩盖密码明文。那么如何解决呢?

办法

TextInputLayout在xml布局中是这样使用的

<com.google.android.material.textfield.TextInputLayout
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/password_hint"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:startIconDrawable="@drawable/ic_baseline_lock_24"
        app:counterEnabled="true"
        app:counterMaxLength="64"
        app:passwordToggleEnabled="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/text_ssid" >

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/text_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

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

设置密码明文遮掩的行为在xml上没有接口,需要在代码中设置:

// 为TextInputEditText设置transformMethod
findViewById<TextInputEditText>(R.id.text_password).apply {
    transformationMethod = PasswordTransformationMethod.getInstance()
}

原因

TextInputEditText中显示尾部图标的控件为CheckenImageButton,当它处于END_ICON_PASSWORD_TOGGLE时,会使用PasswordToggleEndIconDelegate来处理密码明文遮掩的行为。

而它内部会在每次输入前都根据EditText的状态来调整一次“小眼睛”endIconView的check状态,如下:

new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Make sure the password toggle state always matches the EditText's transformation method.
        endIconView.setChecked(!hasPasswordTransformation());
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {}
};

private boolean hasPasswordTransformation() {
    EditText editText = textInputLayout.getEditText();
    return editText != null && editText.getTransformationMethod() instanceof PasswordTransformationMethod;
}

所以,我们直接调整这个EditText(也就是TextInputEditText)的transformationMethod即可。

推荐阅读更多精彩内容