最近优化公司的登陆注册,需要能够切换到密码明文,虽然公司另外一个项目有此功能,但是他是用一个EditText 和 一个ImageView 组合成的,虽然说也实现了功能,也没什么问题,但总觉得缺少点程序员的精神,于是就有了下面的密码明文切换的edtitext
项目地址 https://github.com/HuangPugang/PasswordEditText
直接上代码
public class PasswordEditText extends EditText implements
OnFocusChangeListener, TextWatcher {
private Drawable mShowDrawable;//显示密码的图片
private Drawable mHideDrawable;//隐藏密码的图片
private boolean isShowPassword = false;//是否显示密码
/**
* 控件是否有焦点
*/
private boolean hasFoucs;
public PasswordEditText(Context context) {
this(context, null);
}
private OnTextChangedListener textChangedListener;
public PasswordEditText(Context context, AttributeSet attrs) {
//这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle);
}
public PasswordEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mShowDrawable = getCompoundDrawables()[2];
if (mShowDrawable == null) {
mShowDrawable = getResources().getDrawable(R.mipmap.ic_pswd_visible);
mHideDrawable = getResources().getDrawable(R.mipmap.ic_pswd_invisible);
}
mShowDrawable.setBounds(0, 0, mShowDrawable.getIntrinsicWidth(), mShowDrawable.getIntrinsicHeight());
mHideDrawable.setBounds(0, 0, mHideDrawable.getIntrinsicWidth(), mHideDrawable.getIntrinsicHeight());
setShowPassword(isShowPassword);
//设置焦点改变的监听
setOnFocusChangeListener(this);
//设置输入框里面内容发生改变的监听
addTextChangedListener(this);
}
public OnTextChangedListener getTextChangedListener() {
return textChangedListener;
}
public void setTextChangedListener(OnTextChangedListener textChangedListener) {
this.textChangedListener = textChangedListener;
}
/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getCompoundDrawables()[2] != null) {
boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) {
isShowPassword = !isShowPassword;
setShowPassword(isShowPassword);
}
}
}
return super.onTouchEvent(event);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
this.hasFoucs = hasFocus;
}
/**
* 是否显示密码
*
* @param isShow
*/
protected void setShowPassword(boolean isShow) {
Drawable right = isShow ? mShowDrawable : mHideDrawable;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
this.setInputType(isShow ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD : (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD));
}
@Override
public void onTextChanged(CharSequence s, int start, int count,
int after) {
if (textChangedListener != null) {
textChangedListener.onTextChanged(s, start, count, after);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (textChangedListener != null) {
textChangedListener.beforeTextChanged(s, start, count, after);
}
}
@Override
public void afterTextChanged(Editable s) {
if (textChangedListener != null) {
textChangedListener.afterTextChanged(s);
}
}
public interface OnTextChangedListener {
void onTextChanged(CharSequence s, int start, int count,
int after);
void beforeTextChanged(CharSequence s, int start, int count,
int after);
void afterTextChanged(Editable s);
}
}
隐藏密码
显示密码