如何在Android XML中用Kotlin实现单开关切换两个密码框可见性?
实现单个密码开关同步切换两个输入框的可见状态
布局设置
先确保布局中仅密码框的TextInputLayout开启密码开关,确认密码框无需配置该属性:
<!-- 密码输入框 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/passwordTil" android:layout_width="match_parent" android:layout_height="wrap_content" app:passwordToggleEnabled="true"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/passwordEt" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" /> </com.google.android.material.textfield.TextInputLayout> <!-- 确认密码输入框 --> <com.google.android.material.textfield.TextInputLayout android:id="@+id/confirmPasswordTil" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/confirmPasswordEt" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" /> </com.google.android.material.textfield.TextInputLayout>
代码实现
通过监听密码开关的点击事件,同步修改两个输入框的密码可见状态:
Kotlin 版本
// 初始化控件 val passwordTil = findViewById<TextInputLayout>(R.id.passwordTil) val passwordEt = findViewById<TextInputEditText>(R.id.passwordEt) val confirmPasswordEt = findViewById<TextInputEditText>(R.id.confirmPasswordEt) // 给密码开关设置点击监听器 passwordTil.setEndIconOnClickListener { // 判断当前密码是否可见 val isVisible = passwordEt.transformationMethod is HideReturnsTransformationMethod // 确定要切换到的状态对应的TransformationMethod val targetMethod = if (isVisible) { PasswordTransformationMethod.getInstance() } else { HideReturnsTransformationMethod.getInstance() } // 同步两个输入框的状态 passwordEt.transformationMethod = targetMethod confirmPasswordEt.transformationMethod = targetMethod // 调整光标到文本末尾,避免位置错乱 passwordEt.setSelection(passwordEt.text?.length ?: 0) confirmPasswordEt.setSelection(confirmPasswordEt.text?.length ?: 0) }
Java 版本
// 初始化控件 TextInputLayout passwordTil = findViewById(R.id.passwordTil); TextInputEditText passwordEt = findViewById(R.id.passwordEt); TextInputEditText confirmPasswordEt = findViewById(R.id.confirmPasswordEt); // 给密码开关设置点击监听器 passwordTil.setEndIconOnClickListener(v -> { // 判断当前密码是否可见 boolean isVisible = passwordEt.getTransformationMethod() instanceof HideReturnsTransformationMethod; // 确定要切换到的状态对应的TransformationMethod TransformationMethod targetMethod = isVisible ? PasswordTransformationMethod.getInstance() : HideReturnsTransformationMethod.getInstance(); // 同步两个输入框的状态 passwordEt.setTransformationMethod(targetMethod); confirmPasswordEt.setTransformationMethod(targetMethod); // 调整光标到文本末尾,避免位置错乱 if (passwordEt.getText() != null) { passwordEt.setSelection(passwordEt.getText().length()); } if (confirmPasswordEt.getText() != null) { confirmPasswordEt.setSelection(confirmPasswordEt.getText().length()); } });
替代方案:使用官方监听器
如果偏好Material组件提供的原生密码切换监听器,可使用addOnPasswordVisibilityToggleListener,它会直接返回切换后的可见状态:
Kotlin 版本
passwordTil.addOnPasswordVisibilityToggleListener(object : TextInputLayout.OnPasswordVisibilityToggleListener { override fun onPasswordVisibilityToggleRequested(isVisible: Boolean) { val targetMethod = if (isVisible) { HideReturnsTransformationMethod.getInstance() } else { PasswordTransformationMethod.getInstance() } passwordEt.transformationMethod = targetMethod confirmPasswordEt.transformationMethod = targetMethod passwordEt.setSelection(passwordEt.text?.length ?: 0) confirmPasswordEt.setSelection(confirmPasswordEt.text?.length ?: 0) } })
注意事项
- 确保项目已依赖Material Components库,否则无法使用
TextInputLayout相关控件。 - 调整光标位置的步骤为可选优化,能避免切换可见性后光标位置异常,提升用户体验。
内容的提问来源于stack exchange,提问作者Kartik
相关产品推荐
相关产品推荐

