可以显示和隐藏密码的EditText

/**
* 可以显示和隐藏密码的EditText
*
* @author xiely.
* @date 17/07/19.
*/
public class ShowHidePasswordEditText extends EditText {

private boolean isShowingPassword = false;
private Drawable drawableEnd;
private Rect bounds;
private boolean leftToRight = true;
private int tintColor = 0;

@DrawableRes
private int visiblityIndicatorShow = R.drawable.ic_visibility_off;
@DrawableRes
private int visiblityIndicatorHide = R.drawable.ic_visibility_on;
private boolean monospace;

public ShowHidePasswordEditText(Context context) {
    super(context);
    init(null);
}

public ShowHidePasswordEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs);
}

public ShowHidePasswordEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(attrs);
}

private void init(AttributeSet attrs) {
    if (attrs != null) {
        TypedArray attrsArray = getContext().obtainStyledAttributes(attrs, R.styleable.ShowHidePasswordEditText);

        visiblityIndicatorShow = attrsArray.getResourceId(R.styleable.ShowHidePasswordEditText_drawable_show, visiblityIndicatorShow);
        visiblityIndicatorHide = attrsArray.getResourceId(R.styleable.ShowHidePasswordEditText_drawable_hide, visiblityIndicatorHide);
        monospace = attrsArray.getBoolean(R.styleable.ShowHidePasswordEditText_monospace, true);
        tintColor = attrsArray.getColor(R.styleable.ShowHidePasswordEditText_tint_color, 0);

        attrsArray.recycle();
    }

    leftToRight = isLeftToRight();

    isShowingPassword = false;
    setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD, true);

    if (!monospace) {
        setTypeface(Typeface.DEFAULT);
    }

    if (!TextUtils.isEmpty(getText())) {
        showPasswordVisibilityIndicator(true);
    }

    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) {
            if (s.length() > 0) {
                showPasswordVisibilityIndicator(true);
            } else {
                showPasswordVisibilityIndicator(false);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private boolean isLeftToRight() {
    // If we are pre JB assume always LTR
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        return true;
    }

    Configuration config = getResources().getConfiguration();
    return !(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
}

@Override
public void setCompoundDrawables(Drawable left, Drawable top,
                                 Drawable right, Drawable bottom) {

    //keep a reference to the right drawable so later on touch we can check if touch is on the drawable
    if (leftToRight && right != null) {
        drawableEnd = right;
    } else if (!leftToRight && left != null) {
        drawableEnd = left;
    }
    if(drawableEnd != null) // 点击范围太小了,容易点不到,故增加drawable大小
        drawableEnd.setBounds(0,0, DimenUtils.dpToPxInt(35),DimenUtils.dpToPxInt(35));
    super.setCompoundDrawables(left, top, right, bottom);
}

public void setTintColor(@ColorInt int tintColor) {
    this.tintColor = tintColor;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_UP && drawableEnd != null) {
        int eventX = (int) event.getRawX();
        int eventY = (int) event.getRawY();
        Rect rect = new Rect();
        getGlobalVisibleRect(rect);
        rect.left = rect.right - 50;
        if (rect.contains(eventX, eventY)){ // 判断是否在点击范围之内
            togglePasswordVisibility();
            event.setAction(MotionEvent.ACTION_CANCEL); // 防止弹出软键盘
        }
    }
    return super.onTouchEvent(event);
}

/**
 * 显示或隐藏小眼睛
 *
 * @param show
 */
private void showPasswordVisibilityIndicator(boolean show) {
    if (show) {
        Drawable original = isShowingPassword ?
                ContextCompat.getDrawable(getContext(), visiblityIndicatorHide) :
                ContextCompat.getDrawable(getContext(), visiblityIndicatorShow);
        original.mutate();

        if (tintColor == 0) {
            setCompoundDrawablesWithIntrinsicBounds(leftToRight ? null : original, null, leftToRight ? original : null, null);
        } else {
            Drawable wrapper = DrawableCompat.wrap(original);
            DrawableCompat.setTint(wrapper, tintColor);
            setCompoundDrawablesWithIntrinsicBounds(leftToRight ? null : wrapper, null, leftToRight ? wrapper : null, null);
        }
    } else {
        setCompoundDrawables(null, null, null, null);
    }
}

private void togglePasswordVisibility() {
    if (isShowingPassword) {
        setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD, true);
    } else {
        setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD, true);
    }
    isShowingPassword = !isShowingPassword;
    showPasswordVisibilityIndicator(true);
}

@Override
protected void finalize() throws Throwable {
    drawableEnd = null;
    bounds = null;
    super.finalize();
}


private void setInputType(int inputType, boolean keepState) {
    int selectionStart = -1;
    int selectionEnd = -1;
    if (keepState) {
        selectionStart = getSelectionStart();
        selectionEnd = getSelectionEnd();
    }
    setInputType(inputType);
    if (keepState) {
        setSelection(selectionStart, selectionEnd);
    }
}


public
@DrawableRes
int getVisiblityIndicatorShow() {
    return visiblityIndicatorShow;
}

public void setVisiblityIndicatorShow(@DrawableRes int visiblityIndicatorShow) {
    this.visiblityIndicatorShow = visiblityIndicatorShow;
}

public
@DrawableRes
int getVisiblityIndicatorHide() {
    return visiblityIndicatorHide;
}

public void setVisiblityIndicatorHide(@DrawableRes int visiblityIndicatorHide) {
    this.visiblityIndicatorHide = visiblityIndicatorHide;
}

public boolean isShowingPassword() {
    return isShowingPassword;
}

}

    <declare-styleable name="ShowHidePasswordEditText">
        <attr name="drawable_hide" format="integer" />
        <attr name="drawable_show" format="integer" />
        <attr name="monospace" format="boolean" />
        <attr name="tint_color" format="color" />
    </declare-styleable>

有什么好的想法和交流意见欢迎留言。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值