作者:邹峰立,微博:zrunker,邮箱:zrunker@yahoo.com,微信公众号:书客创作,个人平台:www.ibooker.cc。
书客创作
往往在开发当中,通常会遇到这样的需求,当用户输入密码之后,输入框的右侧显示睁眼或者闭眼的小图标,点击小图标能够实现密码的显示或者隐藏。这样的功能需求非常常见,不同的开发者可能会使用不能的方法,那么如果使用EditText的DrawableRight该如何实现显示和隐藏输入密码呢?
应用场景
DrawableRight实现隐藏和现实密码功能,常见密码输入框的特殊设置。
主要重难点
1、自定义EditText,构造方法中初始化DrawableRight,通过密码的显示和隐藏状态修改DrawableRight的样式。
2、DrawableRight点击事件的判断和处理。
代码实现
在代码实现之前,首先要了解以下几个方法的含义:
drawable.setBounds(int, int, int, int);
该方法是Drawable类中的一个方法,表示设置图片边界,左上右下。
setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
该方法是设置EditText的Drawable,四个参数分别表示左上右下。
getCompoundDrawables()[i]
该方法是获取EditText的Drawable,获取的是一个数组,该数组有四个值,从0到3分别表示EditText左上右下的Drawable,没有的话则为null。
了解这几个方法之后,接下来分两步实现DrawableRight清空输入值功能。
1、自定义EditText
在cc.ibooker.ibooker目录下创建PasswdEditText,让其继承EditText,并实现构造方法。
public class PasswdEditText extends android.support.v7.widget.AppCompatEditText {
/**
* 右侧Drawable引入
*/
private Drawable mDrawableRight;
/**
* 判断当前密码打开状态,默认关闭状态
*/
private boolean isOpen = false;
// 构造方法 1->2->3
public PasswdEditText(Context context) {
this(context, null);
}
public PasswdEditText(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.editTextStyle);
}
public PasswdEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
// 初始化方法
private void init() {
// Drawable顺序左上右下,0123
// 获取DrawRight内容
mDrawableRight = getCompoundDrawables()[2];
if (mDrawableRight == null) {
// 未设置默认DrawableRight
setmDrawableRight(isOpen);
}
}
// 初始化DrawableRight
public void setmDrawableRight(boolean isOpen) {
int drawableId;
// 通过状态设置DrawableRight的样式
if (!isOpen)
drawableId = R.mipmap.icon_open_eye;
else
drawableId = R.mipmap.icon_close_eye;
// 初始化DrawableRight
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mDrawableRight = getResources().getDrawable(drawableId, null);
} else {
mDrawableRight = getResources().getDrawable(drawableId);
}
// 设置Drawable大小和位置
mDrawableRight.setBounds(0, 0, mDrawableRight.getIntrinsicWidth(), mDrawableRight.getIntrinsicHeight());
// 将其添加到控件上
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], mDrawableRight, getCompoundDrawables()[3]);
}
// 触摸事件
// 判断Drawable是否被点击,如果被点击执行点击事件
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
// 获取控件的DrawableRight
Drawable drawable = getCompoundDrawables()[2];
// 当按下的位置 在EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 与 EditText的宽度 - 图标到控件右边的间距之间,算点击了图标,竖直方向不用考虑
// getTotalPaddingRight获取右侧图标以及右侧Padding和
// getPaddingRight获取右侧Padding值
boolean isTouchRight = event.getX() > (getWidth() - getTotalPaddingRight()) && (event.getX() < ((getWidth() - getPaddingRight())));
if (drawable != null && isTouchRight) {
// 记录状态
isOpen = !isOpen;
// 刷新DrawableRight
setmDrawableRight(isOpen);
// 执行点击事件-隐藏或显示
if (isOpen)
setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
else
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
// 设置光标位置
setSelection(getText().length());
}
break;
}
return super.onTouchEvent(event);
}
}
2、在布局文件中引入自定义EditText
直接将自定义的PasswdEditText,引入布局XML文件即可。
<cc.ibooker.ibooker.PasswdEditText
android:id="@+id/ed_passwd"
android:layout_width="match_parent"
android:layout_height="50dp"
android:drawableEnd="@mipmap/icon_eye_open"
android:drawableRight="@mipmap/icon_eye_open"
android:inputType="textPassword"
android:padding="10dp"/>
3、程序结构图
程序结构图微信公众号:书客创作
网友评论