You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:实现EditText空白时隐藏password_toggle图标

实现密码切换图标随输入内容动态显示/隐藏

默认的password_toggle模式无法实现空内容时隐藏图标的需求,我们可以通过自定义end图标+文本监听的方式来实现和清除图标一致的效果,具体步骤如下:

1. 修改布局文件

将app:endIconMode改为custom,指定初始图标并设置默认隐藏:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/textInputPassword"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
    app:endIconMode="custom"
    app:endIconDrawable="@drawable/ic_baseline_visibility_off_24"
    app:endIconVisible="false"
    android:hint="Password">

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

注:@drawable/ic_baseline_visibility_off_24和后续用到的@drawable/ic_baseline_visibility_24是Material Design官方的密码可见/隐藏图标,可根据项目需求替换为自定义图标。

2. 添加逻辑控制

在Activity/Fragment中实现文本监听和密码切换功能:

Kotlin示例

val textInputPassword = findViewById<TextInputLayout>(R.id.textInputPassword)
val edittextPassword = findViewById<TextInputEditText>(R.id.edittextPassword)

// 监听文本变化,控制图标显示状态
edittextPassword.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        textInputPassword.isEndIconVisible = !s.isNullOrEmpty()
    }
    override fun afterTextChanged(s: Editable?) {}
})

// 密码切换点击事件
textInputPassword.setEndIconOnClickListener {
    val isVisible = edittextPassword.inputType == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
    if (isVisible) {
        // 切换为隐藏密码
        edittextPassword.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
        textInputPassword.endIconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_baseline_visibility_off_24)
    } else {
        // 切换为显示密码
        edittextPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
        textInputPassword.endIconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_baseline_visibility_24)
    }
    // 保持光标在文本末尾
    edittextPassword.setSelection(edittextPassword.text?.length ?: 0)
}

Java示例

TextInputLayout textInputPassword = findViewById(R.id.textInputPassword);
TextInputEditText edittextPassword = findViewById(R.id.edittextPassword);

// 监听文本变化
edittextPassword.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        textInputPassword.setEndIconVisible(s != null && !s.toString().isEmpty());
    }
    @Override
    public void afterTextChanged(Editable s) {}
});

// 密码切换逻辑
textInputPassword.setEndIconOnClickListener(v -> {
    boolean isVisible = edittextPassword.getInputType() == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
    if (isVisible) {
        edittextPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        textInputPassword.setEndIconDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_visibility_off_24));
    } else {
        edittextPassword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
        textInputPassword.setEndIconDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_visibility_24));
    }
    // 修正光标位置
    edittextPassword.setSelection(edittextPassword.getText() != null ? edittextPassword.getText().length() : 0);
});

注意事项

  • 确保项目已引入Material Components库,建议使用较新版本避免兼容性问题。
  • 切换输入类型后设置光标位置是为了避免光标跳转到文本开头的问题,提升用户体验。

内容的提问来源于stack exchange,提问作者TexD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:10:51