1

我们在注册或者登录App时,难免会需要输入密码。有时候我们身旁可能有其他人在,为了不让密码“赤裸裸”地暴露在他人眼皮底下,密码字符串通常会默认显示为暗文(也就是星号或者圆点)。但还有一种情况是我们在输入密码时有时会小手一抖,会多按几下或者输错了密码,因为都是暗文,我们就只好把密码全都删掉重新输入了。这个时候我们就又怀念起能看到密码的日子了。那么有没有方法让密码在明暗文中来回切换呢。答案是肯定的,而且还不止一种!下面我们就来尝试一下吧。

1、只需一个简单的ImageView

新建一个PasswordActivity,它的布局很简单:密码输入框就是一个EditText,控制密码是否可见的控件我们使用ImageView。当密码为明文时,ImageView填充的是睁开眼睛的图片;当密码为暗文时,则是一张闭上眼睛的图片。

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/image"
            android:hint="请输入密码"
            android:inputType="textPassword"
            android:textColorHint="#b7b6b6" />

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@mipmap/hide_pwd_image" />
    </RelativeLayout>

在初始化完控件之后,我们创建一个控制密码是否可见的方法:

       //密碼是否可見
    private boolean isPwdVisible = false;
    /**
     * 设置密码是否可见
     */
    private void setPasswordVisible() {
        //ImageView点击事件
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //修改密码是否可见的状态
                isPwdVisible = !isPwdVisible;
                //設置密碼是否可見
                if (isPwdVisible) {
                    //设置密码为明文,并更改眼睛图标
                    editText1.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                    imageView.setImageResource(R.mipmap.show_pwd_image);
                } else {
                    //设置密码为暗文,并更改眼睛图标
                    editText1.setTransformationMethod(PasswordTransformationMethod.getInstance());
                    imageView.setImageResource(R.mipmap.hide_pwd_image);
                }
                //设置光标位置的代码需放在设置明暗文的代码后面
                editText1.setSelection(editText1.getText().toString().length());
            }
        });

setTransformationMethod是TextView的方法(EditText继承于TextView,所以我们也可以使用它),谷歌文档是这样描述它的作用的:

Sets the transformation that is applied to the text that this TextView is displaying.

大概意思是在TextView显示时,能够对其中的文字进行变换。它需要传入一个TransformationMethod的对象作为参数,至于在密码可见和不可见时传入什么,大家看上面的代码就知道了。

那么我们怎么判断当前的密码是处于什么状态呢?这个也不难,我们可以声明一个布尔值变量isPwdVisible,默认为false,也就是密码不可见。每次改变密码的可见状态时,对其取反就可以了。另外,为了让用户体验更好,每次切换状态后都让光标移至输入框的最末端。

2、巧用CheckBox

大家仔细想想,我们点击眼睛图片,密码就在可见和不可见两种状态中切换,这是不是看起来很眼熟呢?没错,这不就跟CheckBox一样嘛!每次点击就进行一次取反操作。所以我们也可以用CheckBox来代替ImageView,然后将背景替换为眼睛图片即可:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editText2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/checkbox"
            android:hint="请输入密码"
            android:inputType="textPassword"
            android:textColorHint="#b7b6b6" />

        <CheckBox
            android:id="@+id/checkbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@mipmap/hide_pwd_image"
            android:button="@null"
            android:checked="false"
             />
    </RelativeLayout>

记得一定要写上android:button="@null"把CheckBox原本的方框去掉。

换成CheckBox后,我们就不用声明布尔值变量,而是直接可以调用CheckBox的监听事件:

        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    //CheckBox选中,显示明文
                    editText2.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                    checkBox.setBackgroundResource(R.mipmap.show_pwd_image);
                } else {
                    //CheckBox取消选中,显示暗文
                    editText2.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    checkBox.setBackgroundResource(R.mipmap.hide_pwd_image);
                }
                //光标移至最末端
                editText2.setSelection(editText2.getText().toString().length());
            }
        });

这里我们使用了第二种方法来设置密码是否可见:调用setInputType方法来改变EditText的输入状态。InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD可以设置密码可见,InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD则可以隐藏密码。

方法都介绍完了,大家可以看看实现的效果,都是一样的:
效果图

3、总结

本文介绍了使用使用不同控件和不同函数来设置EditText的密码是否可见,实际上两两组合起来有四种了。代码很简单,而且我是写在一个大的project中的,所以源码就只放主要文件和图片资源了。
资源下载


lindroid
214 声望13 粉丝

Android中级魔法师