编辑文本密码切换Android

34

我希望向用户展示输入类型为密码的文本密码。

我像这样在切换图标上实现了手势监听器-

public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (view.getId())
        {
            case R.id.ivPasswordToggle:

                switch ( motionEvent.getAction() ) {
                    case MotionEvent.ACTION_DOWN:
                        Toast.makeText(getContext(),"show",Toast.LENGTH_SHORT).show();
                        etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                        break;
                    case MotionEvent.ACTION_UP:
                        etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT);
                        Toast.makeText(getContext(),"hide",Toast.LENGTH_SHORT).show();
                        break;
                }
                break;
        }
        return true;
    }

我不知道出了什么问题,任何帮助将不胜感激。


我的提示信息正常工作,但对编辑文本的文本没有影响。 - Apoorv Singh
10个回答

65

(已更新为AndroidX)

自Support库v24.2.0以来,您可以非常轻松地实现这一点。

您需要做的只是:

  1. 将design库添加到您的依赖项中

 dependencies {
     implementation "com.google.android.material:material:1.2.1"
 }
  • TextInputEditTextTextInputLayout结合使用

  •  <com.google.android.material.textfield.TextInputLayout
         xmlns:app="http://schemas.android.com/apk/res-auto"
         android:id="@+id/etPasswordLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:passwordToggleEnabled="true">
    
         <android.support.design.widget.TextInputEditText
             android:id="@+id/etPassword"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:hint="@string/password_hint"
             android:inputType="textPassword"/>
     </com.google.android.material.textfield.TextInputLayout>
    

    passwordToggleEnabled 属性将显示密码切换按钮

    1. 在根布局中不要忘记添加 xmlns:app="http://schemas.android.com/apk/res-auto"

    2. 您可以使用以下内容自定义密码切换按钮:

    app:passwordToggleDrawable - 用作密码可见性切换图标的 Drawable。
    app:passwordToggleTint - 用于密码可见性切换的图标。
    app:passwordToggleTintMode - 用于应用背景色调的混合模式。

    更多细节请参考 TextInputLayout 文档

    输入图片描述


    4
    默认情况下,我希望密码不可见。我该如何实现这一点? - Shiva Acharjee
    如何使用支持库23.4.0实现相同的功能。 - HONy
    如何去除背景水平线? - OhhhThatVarun
    1
    app:endIconMode="password_toggle" 应用程序:endIconMode="password_toggle" - Alfin
    1
    @ShivaAcharjee 你可以通过将android:inputType设置为xml或编程方式来实现此操作。它的值应为"text|textPassword"。 - Kostadin Georgiev
    有人知道如何设置密码切换的选中或未选中吗? - ladytoky0

    12
    请尝试这段代码。
    public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (view.getId())
            {
                case R.id.ivPasswordToggle:
    
                    switch ( motionEvent.getAction() ) {
                        case MotionEvent.ACTION_DOWN:
                            Toast.makeText(getContext(),"show",Toast.LENGTH_SHORT).show();
                             etPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                            break;
                        case MotionEvent.ACTION_UP:
                             etPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
                            Toast.makeText(getContext(),"hide",Toast.LENGTH_SHORT).show();
                            break;
                    }
                    break;
            }
            return true;
        }
    

    希望它能够正常工作,谢谢。


    1
    谢谢。代码运行良好,但每次我点击可绘制对象时,编辑文本光标都会移到第一个位置。 - Apoorv Singh
    1
    在两个switch case中尝试一下这个……etPassword.setSelection(etPassword.getText().length()); 然后告诉我,如果不起作用的话。 - user3539940
    1
    我得到了答案,我必须在action down和action up中都添加edittext.setSelection(Position)。 - Apoorv Singh

    12
    如果您不想要任何额外的布尔值或依赖关系,那么:

    如果您不想要任何额外的布尔值或依赖关系,则

        <EditText
            android:id="@+id/et_input_pass"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_marginTop="3dp"
            android:layout_marginStart="56dp"
            android:layout_marginEnd="56dp"
            android:hint="Password"
            android:inputType="textPassword"
            android:singleLine="true"
            android:textSize="13sp"
            android:background="@color/transparent"
            android:theme="@style/MyEditText" />
    

    password_toggle_imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (et_input_pass.getTransformationMethod().getClass().getSimpleName() .equals("PasswordTransformationMethod")) {
                et_input_pass.setTransformationMethod(new SingleLineTransformationMethod());
            }
            else {
                et_input_pass.setTransformationMethod(new PasswordTransformationMethod());
            }
    
            et_input_pass.setSelection(et_input_pass.getText().length());
        }
    });
    

    就是这样!


    1
    这应该是一个被接受的答案。简单而快捷。 - Himani

    7
    尝试以下方法。这里,我们设置了一个复合绘图,当单击它时,会显示或隐藏密码:
    private boolean passwordShown = false;
    
    private void addPasswordViewToggle() {
            getPasswordEditText().setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    final int DRAWABLE_RIGHT = 2; //index
    
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        if (event.getRawX() >= (getPasswordEditText().getRight() - getPasswordEditText().getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                            if (passwordShown) {
                                passwordShown = false;
                                // 129 is obtained by bitwise ORing InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD
                                getPasswordEditText().setInputType(129);
    
                                // Need to call following as the font is changed to mono-space by default for password fields
                                getPasswordEditText().setTypeface(Typeface.SANS_SERIF);
                                getPasswordEditText().setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.locked_icon, 0); // This is lock icon
                            } else {
                                passwordShown = true;
                                getPasswordEditText().setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
    
                                getPasswordEditText().setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.unlocked_icon, 0); // Unlock icon
                            }
    
                            return true;
                        }
                    }
                    return false;
                }
            });
        }
    

    3
     fragmentLoginBinding.imageViewEye.setOnClickListener(v -> {
            if (!isPasswordVisible) {
                fragmentLoginBinding.editTextPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                fragmentLoginBinding.imageViewEye.setImageDrawable(getResources().getDrawable(R.mipmap.feather_eye_crossed));
                isPasswordVisible = true;
            } else {
                fragmentLoginBinding.editTextPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
                fragmentLoginBinding.imageViewEye.setImageDrawable(getResources().getDrawable(R.mipmap.feather_eye));
                isPasswordVisible = false;
            }
        });
    

    2

    app:passwordToggleEnabled="true"

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:passwordToggleEnabled="true">
    
        <androidx.appcompat.widget.AppCompatEditText
            android:id="@+id/etPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter Password"
            android:inputType="textPassword"
            android:maxLines="1" />
    
    </com.google.android.material.textfield.TextInputLayout>
    

    这个答案与几年前发布的被接受的答案有何不同?请考虑给现有的答案点赞,而不是再次粘贴相同的答案。 - Amir Dora.

    0

    我想提出一个受@shanezzar's answer启发的解决方案,它不需要对现有的遗留android:inputType="textPassword" EditText布局进行更改(例如添加显示密码图标/复选框)。当EditText获得输入焦点时,它会简单地显示密码,并在EditText失去焦点时隐藏密码(password是一个EditText):

    password.setOnFocusChangeListener((v, hasFocus) -> {
       if (hasFocus) {
          password.setTransformationMethod(new SingleLineTransformationMethod());
       } else {
          password.setTransformationMethod(new PasswordTransformationMethod());
       }
       // move cursor to end of text
       password.setSelection(password.getText().length());
    });
    

    0
    实现类似下面的TextInput。赋予该功能的主要属性是app:passwordToggleEnabled="true"。
    <com.google.android.material.textfield.TextInputLayout
                    android:id="@+id/resetpasswordactivity_textinputlayout_newpassword"
                    android:layout_width="0dp"
                    android:layout_height="60dp"
                    app:passwordToggleEnabled="true"
                    android:theme="@style/loginActivityHintStyle"
                    app:layout_constraintBottom_toTopOf="@+id/resetpasswordactivity_textinputlayout_newconfirmpassword"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/resetpasswordactivity_textinputlayout_resetcode"
                    app:layout_constraintVertical_bias="0.15">
    
                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/resetpasswordactivity_textinputedittext_newpassword"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:hint="Password"
                        android:inputType="textPassword"
                        android:labelFor="@id/resetpasswordactivity_textinputedittext_newpassword"
                        android:maxLength="100"
                        android:textColor="@drawable/black_inputtext_color"
                        />
                </com.google.android.material.textfield.TextInputLayout>
    

    0

    如果你想使用EditText或AppCompatEditText,你可以通过以下方式实现所需的输出:

    <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/layout_password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/spinner_role"
                    >
    
                    <androidx.appcompat.widget.AppCompatEditText
                        android:id="@+id/edit_text_password"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="10dp"
                        android:autofillHints="@string/password"
                        android:hint="@string/password"
                        android:inputType="textPassword"
                        android:textSize="16sp"
                        app:backgroundTint="#59A6B6"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />
    
                    <androidx.appcompat.widget.AppCompatImageView
                        android:id="@+id/button_password_toggle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginEnd="4dp"
                        android:src="@drawable/ic_visibility_off"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintTop_toTopOf="@+id/register_user_password_et" />
    
                </androidx.constraintlayout.widget.ConstraintLayout>
    

    在你的 .kt 文件中;
    if (registerUserBinding.editTextPassword.transformationMethod.equals(
                PasswordTransformationMethod.getInstance()
            )
        ) {
            registerUserBinding.registerUserPasswordEt.transformationMethod =
                HideReturnsTransformationMethod.getInstance()
            registerUserBinding.buttonPasswordToggle.setImageDrawable(
                ContextCompat.getDrawable(
                    registerUserBinding.registerUserPasswordEt.context,
                    R.drawable.ic_visibility
                )
            )
    
        } else {
            registerUserBinding.editTextPassword.transformationMethod =
                PasswordTransformationMethod.getInstance()
            registerUserBinding.buttonPasswordToggle.setImageDrawable(
                ContextCompat.getDrawable(
                    registerUserBinding.registerUserPasswordEt.context,
                    R.drawable.ic_visibility_off
                )
            )
        }
    

    0

    这是对已接受答案的一个小补充,针对那些想要为切换按钮实现自定义可绘制的人。

    1. 在你的资源中:

    drawable/password_toggle.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:state_checked="true"
            android:drawable="@drawable/eye"
            app:tint="@color/black_600_8a"/>
        <item
            android:drawable="@drawable/eye_closed"
            app:tint="@color/black_600_8a" />
    </selector>
    

    state_checked 是密码可见状态

    注意:在 drawable 中使用 app:tint 而不是在布局中使用 android:endIconTint 来改变您的切换按钮的颜色,因为后者无法与选择器正常工作

    1. 在您的布局 xml 中
    <com.google.android.material.textfield.TextInputLayout
        ...
        app:endIconMode="password_toggle"
        app:endIconDrawable="@drawable/password_toggle">
    
            <com.google.android.material.textfield.TextInputEditText
                ...
                android:inputType="textPassword"/>
    </com.google.android.material.textfield.TextInputLayout>
    

    希望这篇文章能像它对我有用一样,对其他人也有所帮助!

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