android中edittext设置密码格式,Android 自定义EditText(带清理、密码可见、不可见)...

实际开发中经常会遇到输入框,各种不同的需求,在一般情况下,清除内容,以及密码可见与不可见基本很常见,那么不废话直接上代码!

在res\values\attrs.xml中

.java

import android.animation.ObjectAnimator;

import android.animation.ValueAnimator;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.RectF;

import android.os.Build;

import android.text.InputType;

import android.util.AttributeSet;

import android.util.Property;

import android.view.MotionEvent;

import android.view.animation.Animation;

import android.view.animation.CycleInterpolator;

import android.view.animation.TranslateAnimation;

import androidx.annotation.Nullable;

import androidx.appcompat.widget.AppCompatEditText;

import com.chaian.phone.imlibrary.R;

/**

* 自定义可带清除、密码显示不显示的输入框

*/

public class SeniorEditText extends AppCompatEditText {

/**

* 边框样式

*/

private static final String STYLE_RECT = "rectangle";//矩形

private static final String STYLE_ROUND_RECT = "roundRect";//圆角矩形

private static final String STYLE_HALF_RECT = "halfRect";//半矩形

private static final String STYLE_ANIMATOR = "animator";//动画特效

private static final int DEFAULT_ROUND_RADIUS = 20;//圆角矩形圆角度

private static final int ANIMATOR_TIME = 200;//动画时间

private static final int DEFAULT_FOCUSED_STROKE_WIDTH = 8;//获取到焦点的边框宽

private static final int DEFAULT_UNFOCUSED_STROKE_WIDTH = 4;//未获取焦点的边框宽

private static final int DEFAULT_STYLE_COLOR = Color.RED;//边框默认颜色

//按钮间隔

private int visible_res_padding = 0;

//按钮宽度

private int visible_res_width = 0;

//右内边距

private int mTextPaddingRight;

//需要显示的drawable 资源id

private int clear_res_id = 0;

private int visible_res_id = 0;

private int invisible_res_id = 0;

//需要显示的bitmap---通过drawable 资源id来

private Bitmap clear_bitmap;

private Bitmap visible_bitmap;

private Bitmap invisible_bitmap;

private String edit_border_style = "";

private int edit_border_color = -1;

//出现和消失动画

private ValueAnimator show_animator;

private ValueAnimator dismiss_animator;

//状态值

private boolean clear_image_isShow = false;

private boolean show_password_image_isShow = false;

private boolean dismiss_password_image_isShow = false;

private boolean isAnimatorRunning = false;

private int mAnimatorProgress = 0;

private ObjectAnimator mAnimator;

//自定义属性动画

private static final Property BORDER_PROGRESS

= new Property(Integer.class, "borderProgress") {

@Override

public Integer get(SeniorEditText seniorEditText) {

return seniorEditText.getBorderProgress();

}

@Override

public void set(SeniorEditText seniorEditText, Integer value) {

seniorEditText.setBorderProgress(value);

}

};

private Paint mPaint;

public SeniorEditText(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

init(context, attrs);

}

public SeniorEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context, attrs);

}

private void init(Context context, AttributeSet attrs) {

//抗锯齿和位图滤波

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

//读取xml文件中的配置

if (attrs != null) {

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SeniorEditText);

//获取清除图标资源

clear_res_id = array.getResourceId(R.styleable.SeniorEditText_clearDrawable, R.drawable.ic_content_clear);

//获取可见图标资源

visible_res_id = array.getResourceId(R.styleable.SeniorEditText_visibleDrawable, R.drawable.ic_content_visible);

//获取不可见图标资源

invisible_res_id = array.getResourceId(R.styleable.SeniorEditText_invisibleDrawable, R.drawable.ic_content_invisible);

//可见图标按钮默认宽

visible_res_width = array.getDimensionPixelSize(R.styleable.SeniorEditText_visibleDrawableWidth, dp2px(context,24));

//可见图标按钮默认内边距

visible_res_padding = array.getDimensionPixelSize(R.styleable.SeniorEditText_visibleDrawableSpacing, dp2px(context,5));

//输入框边框样式

edit_border_style = array.getString(R.styleable.SeniorEditText_editFrameStyle);

//输入框边框颜色

edit_border_color = array.getColor(R.styleable.SeniorEditText_editFrameColor, DEFAULT_STYLE_COLOR);

array.recycle();

}

//初始化按钮显示的Bitmap

clear_bitmap = createBitmap(context, clear_res_id, R.drawable.ic_content_clear);

visible_bitmap = createBitmap(context, visible_res_id, R.drawable.ic_content_visible);

invisible_bitmap = createBitmap(context, invisible_res_id, R.drawable.ic_content_invisible);

//如果自定义,则使用自定义的值,否则使用默认值

if (visible_res_padding == 0) {

visible_res_padding = dp2px(context,5);

}

if (visible_res_width == 0) {

visible_res_width = dp2px(context,24);

}

//给文字设置一个padding,避免文字和按钮重叠了

mTextPaddingRight = visible_res_padding * 4 + visible_res_width * 2;

//按钮出现和消失的动画

show_animator = ValueAnimator.ofFloat(1f, 0f).setDuration(ANIMATOR_TIME);

dismiss_animator = ValueAnimator.ofFloat(0f, 1f).setDuration(ANIMATOR_TIME);

//是否是密码样式

show_password_image_isShow = getInputType() == (InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//设置右内边距, 防止清除按钮和文字重叠

setPadding(getPaddingLeft(), getPaddingTop(), mTextPaddingRight, getPaddingBottom());

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

mPaint.setStyle(Paint.Style.STROKE);

//使用自定义颜色。如未定义,则使用默认颜色

if (edit_border_color != -1) {

mPaint.setColor(edit_border_color);

} else {

mPaint.setColor(DEFAULT_STYLE_COLOR);

}

//控件获取焦点时,加粗边框

if (isFocused()) {

mPaint.setStrokeWidth(DEFAULT_FOCUSED_STROKE_WIDTH);

} else {

mPaint.setStrokeWidth(DEFAULT_UNFOCUSED_STROKE_WIDTH);

}

//绘制边框

drawBorder(canvas);

//绘制清空和明文显示按钮

drawButtons(canvas);

}

private void drawBorder(Canvas canvas) {

int width = getWidth();

int height = getHeight();

switch (edit_border_style) {

//矩形样式

case STYLE_RECT:

setBackground(null);

canvas.drawRect(0, 0, width, height, mPaint);

break;

//圆角矩形样式

case STYLE_ROUND_RECT:

setBackground(null);

float roundRectLineWidth = 0;

if (isFocused()) {

roundRectLineWidth = DEFAULT_FOCUSED_STROKE_WIDTH / 2;

} else {

roundRectLineWidth = DEFAULT_UNFOCUSED_STROKE_WIDTH / 2;

}

mPaint.setStrokeWidth(roundRectLineWidth);

if (Build.VERSION.SDK_INT >= 21) {

canvas.drawRoundRect(

roundRectLineWidth / 2, roundRectLineWidth / 2, width - roundRectLineWidth / 2, height - roundRectLineWidth / 2,

DEFAULT_ROUND_RADIUS, DEFAULT_ROUND_RADIUS,

mPaint);

} else {

canvas.drawRoundRect(

new RectF(roundRectLineWidth / 2, roundRectLineWidth / 2, width - roundRectLineWidth / 2, height - roundRectLineWidth / 2),

DEFAULT_ROUND_RADIUS, DEFAULT_ROUND_RADIUS,

mPaint);

}

break;

//半矩形样式

case STYLE_HALF_RECT:

setBackground(null);

canvas.drawLine(0, height, width, height, mPaint);

canvas.drawLine(0, height / 2, 0, height, mPaint);

canvas.drawLine(width, height / 2, width, height, mPaint);

break;

//动画特效样式

case STYLE_ANIMATOR:

setBackground(null);

if (isAnimatorRunning) {

canvas.drawLine(width / 2 - mAnimatorProgress, height, width / 2 + mAnimatorProgress, height, mPaint);

if (mAnimatorProgress == width / 2) {

isAnimatorRunning = false;

}

} else {

canvas.drawLine(0, height, width, height, mPaint);

}

break;

default:

break;

}

}

private void drawButtons(Canvas canvas) {

if (clear_image_isShow) {

//播放按钮出现的动画

if (dismiss_animator.isRunning()) {

float scale = (float) dismiss_animator.getAnimatedValue();

drawClearButton(scale, canvas);

if (show_password_image_isShow) {

drawVisibleButton(scale, canvas, dismiss_password_image_isShow);

}

invalidate();

//绘制静态的按钮

} else {

drawClearButton(1, canvas);

if (show_password_image_isShow) {

drawVisibleButton(1, canvas, dismiss_password_image_isShow);

}

}

} else {

//播放按钮消失的动画

if (show_animator.isRunning()) {

float scale = (float) show_animator.getAnimatedValue();

drawClearButton(scale, canvas);

if (show_password_image_isShow) {

drawVisibleButton(scale, canvas, dismiss_password_image_isShow);

}

invalidate();

}

}

}

private void drawClearButton(float scale, Canvas canvas) {

int right = (int) (getWidth() + getScrollX() - visible_res_padding - visible_res_width * (1f - scale) / 2f);

int left = (int) (getWidth() + getScrollX() - visible_res_padding - visible_res_width * (scale + (1f - scale) / 2f));

int top = (int) ((getHeight() - visible_res_width * scale) / 2);

int bottom = (int) (top + visible_res_width * scale);

Rect rect = new Rect(left, top, right, bottom);

canvas.drawBitmap(clear_bitmap, null, rect, mPaint);

}

private void drawVisibleButton(float scale, Canvas canvas, boolean isVisible) {

int right = (int) (getWidth() + getScrollX() - visible_res_padding * 3 - visible_res_width - visible_res_width * (1f - scale) / 2f);

int left = (int) (getWidth() + getScrollX() - visible_res_padding * 3 - visible_res_width - visible_res_width * (scale + (1f - scale) / 2f));

int top = (int) ((getHeight() - visible_res_width * scale) / 2);

int bottom = (int) (top + visible_res_width * scale);

Rect rect = new Rect(left, top, right, bottom);

if (isVisible) {

canvas.drawBitmap(visible_bitmap, null, rect, mPaint);

} else {

canvas.drawBitmap(invisible_bitmap, null, rect, mPaint);

}

}

// 清除按钮出现时的动画效果

private void startVisibleAnimator() {

endAllAnimator();

dismiss_animator.start();

invalidate();

}

// 清除按钮消失时的动画效果

private void startGoneAnimator() {

endAllAnimator();

show_animator.start();

invalidate();

}

// 结束所有动画

private void endAllAnimator() {

show_animator.end();

dismiss_animator.end();

}

@Override

protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {

super.onFocusChanged(focused, direction, previouslyFocusedRect);

//播放按钮出现和消失动画

if (focused && getText().length() > 0) {

if (!clear_image_isShow) {

clear_image_isShow = true;

startVisibleAnimator();

}

} else {

if (clear_image_isShow) {

clear_image_isShow = false;

startGoneAnimator();

}

}

//实现动画特效样式

if (focused && edit_border_style.equals(STYLE_ANIMATOR)) {

isAnimatorRunning = true;

mAnimator = ObjectAnimator.ofInt(this, BORDER_PROGRESS, 0, getWidth() / 2);

mAnimator.setDuration(ANIMATOR_TIME);

mAnimator.start();

}

}

protected void setBorderProgress(int borderProgress) {

mAnimatorProgress = borderProgress;

postInvalidate();

}

protected int getBorderProgress() {

return mAnimatorProgress;

}

@Override

protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {

super.onTextChanged(text, start, lengthBefore, lengthAfter);

if (text.length() > 0 && isFocused()) {

if (!clear_image_isShow) {

clear_image_isShow = true;

startVisibleAnimator();

}

} else {

if (clear_image_isShow) {

clear_image_isShow = false;

startGoneAnimator();

}

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_UP) {

boolean clearTouched =

(getWidth() - visible_res_padding - visible_res_width < event.getX())

&& (event.getX() < getWidth() - visible_res_padding)

&& isFocused();

boolean visibleTouched =

(getWidth() - visible_res_padding * 3 - visible_res_width * 2 < event.getX())

&& (event.getX() < getWidth() - visible_res_padding * 3 - visible_res_width)

&& show_password_image_isShow && isFocused();

if (clearTouched) {

setError(null);

setText("");

return true;

} else if (visibleTouched) {

if (dismiss_password_image_isShow) {

dismiss_password_image_isShow = false;

setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT);

setSelection(getText().length());

invalidate();

} else {

dismiss_password_image_isShow = true;

setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);

setSelection(getText().length());

invalidate();

}

return true;

}

}

return super.onTouchEvent(event);

}

/**

* 开始晃动的入口

*/

public void startShakeAnimation() {

if (getAnimation() == null) {

setAnimation(shakeAnimation(4));

}

startAnimation(getAnimation());

}

/**

* 晃动动画

*

* @param counts 0.5秒钟晃动多少下

* @return

*/

private Animation shakeAnimation(int counts) {

Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);

translateAnimation.setInterpolator(new CycleInterpolator(counts));

translateAnimation.setDuration(500);

return translateAnimation;

}

private Bitmap createBitmap(Context context, int resId, int defResId) {

if (resId != 0) {

return BitmapFactory.decodeResource(context.getResources(), resId);

} else {

return BitmapFactory.decodeResource(context.getResources(), defResId);

}

}

public int dp2px(Context context, float dpValue){

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpValue,context.getResources().getDisplayMetrics());

}

}

XML

android:inputType="textPassword"

app:clearDrawable="@drawable/ic_content_clear"

app:visibleDrawable="@drawable/ic_content_visible"

app:invisibleDrawable="@drawable/ic_content_invisible"

app:editFrameStyle="roundRect"

app:editFrameColor="#5D2BC5"

android:layout_marginTop="30dp"

android:layout_marginStart="20dp"

android:layout_marginEnd="20dp"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

资源图标

7717cda9eb2a

ic_content_clear.png

7717cda9eb2a

ic_content_invisible.png

7717cda9eb2a

ic_content_visible.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值