package discount.xcar.com.myapplication; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.util.Timer; import java.util.TimerTask; /** * Created by user on 2017/5/12. */ public class MyPasswordView extends View { private int passwordLength = 4;//密码位数 private long cursorFlashTime = 500;//光标闪烁间隔时间 private int passwordPadding = dp2px(10);//每个密码间的间隔 private int passwordSize = dp2px(40);//单个密码的大小 private int borderColor = Color.parseColor("#c0c0c0");//边框颜色 private int borderWidth= dp2px(5);//下划线粗细 private int cursorPosition;//光标位置 private int cursorWidth = dp2px(2);//光标粗细 private int cursorHeight;//光标高度 private int cursorColor=Color.parseColor("#c8c8c8");//光标颜色 private boolean isCursorShowing;//光标是否正在显示中 private boolean isCursorEnable = true;//光标是否开启 private boolean isInputComplete;//是否输入完成 private int cipherTextSize;//密文符号大小 private boolean cipherEnable=true;//密文是否开启 private static String CIPHER_TEXT = "*"; private Context mContext; private Paint mPaint; private String []password = {"1","1","1","1"}; private TimerTask mTimerTask; private Timer mTimer; public MyPasswordView(Context context) { this(context, null); } public MyPasswordView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyPasswordView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { mContext = context; mPaint = new Paint(); mPaint.setColor(Color.GRAY); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mTimerTask = new TimerTask() { @Override public void run() { isCursorShowing = !isCursorShowing; postInvalidate(); } }; mTimer = new Timer(); } //1、测量 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int width = 0; switch (widthMode) { case MeasureSpec.UNSPECIFIED: case MeasureSpec.AT_MOST: width = passwordSize * passwordLength + passwordPadding * (passwordLength - 1); break; case MeasureSpec.EXACTLY: width = MeasureSpec.getSize(widthMeasureSpec); passwordSize = (width - passwordPadding * (passwordLength - 1)) / passwordLength; break; } Log.d("MyPasswordView","widht:"+width+" height:"+passwordSize); setMeasuredDimension(width, passwordSize); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //文本大小 cipherTextSize = passwordSize / 2; //光标宽度 cursorWidth = dp2px(2); //光标高度 cursorHeight = passwordSize / 2; } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mTimer.schedule(mTimerTask,0,cursorFlashTime); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mTimer.cancel(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawUnderLine(canvas); drawcipherText(canvas); drawCursor(canvas); } /** * 绘制光标 * @param canvas */ private void drawCursor(Canvas canvas) { mPaint.setColor(cursorColor); mPaint.setStrokeWidth(cursorWidth); mPaint.setStyle(Paint.Style.FILL); //光标未显示 && 开启光标 && 输入位数未满 && 获得焦点 if (!isCursorShowing && isCursorEnable && !isInputComplete) { // 起始点x = paddingLeft + 单个密码框大小 / 2 + (单个密码框大小 + 密码框间距) * 光标下标 // 起始点y = paddingTop + (单个密码框大小 - 光标大小) / 2 // 终止点x = 起始点x // 终止点y = 起始点y + 光标高度 canvas.drawLine((getPaddingLeft() + passwordSize / 2) + (passwordSize + passwordPadding) * cursorPosition, getPaddingTop() + (passwordSize - cursorHeight) / 2, (getPaddingLeft() + passwordSize / 2) + (passwordSize + passwordPadding) * cursorPosition, getPaddingTop() + (passwordSize + cursorHeight) / 2, mPaint); } } /** * 画下划线 * @param canvas */ private void drawUnderLine(Canvas canvas) { mPaint.setColor(borderColor); mPaint.setStrokeWidth(borderWidth); mPaint.setStyle(Paint.Style.FILL); //循环绘制下划线 for (int i = 0; i < passwordLength; i++) { canvas.drawLine(getPaddingLeft() + (passwordSize + passwordPadding) * i, (getPaddingTop() + passwordSize), getPaddingLeft() + (passwordSize + passwordPadding) * i+passwordSize, (getPaddingTop() + passwordSize), mPaint); } } /** * 绘制密码代替符号 * @param canvas */ private void drawcipherText(Canvas canvas){ //画笔初始化 mPaint.setColor(Color.GRAY); mPaint.setTextSize(cipherTextSize); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setStyle(Paint.Style.FILL); //文字居中的处理 Rect r = new Rect(); canvas.getClipBounds(r); int cHeight = r.height(); mPaint.getTextBounds(CIPHER_TEXT, 0, CIPHER_TEXT.length(), r); float y = cHeight / 2f + r.height() / 2f - r.bottom; Log.d("MyPasswordView","y:"+y+" cHeight:"+cHeight+" height:"+r.height()+" r.bottom:"+r.bottom); //根据输入的密码位数,进行for循环绘制 for (int i = 0; i < password.length; i++) { if (!TextUtils.isEmpty(password[i])) { // x = paddingLeft + 单个密码框大小/2 + ( 密码框大小 + 密码框间距 ) * i // y = paddingTop + 文字居中所需偏移量 if (cipherEnable) { //没有开启明文显示,绘制密码密文 canvas.drawText(CIPHER_TEXT, (getPaddingLeft() + passwordSize / 2) + (passwordSize + passwordPadding) * i, getPaddingTop() + y, mPaint); } else { //明文显示,直接绘制密码 canvas.drawText(password[i], (getPaddingLeft() + passwordSize / 2) + (passwordSize + passwordPadding) * i, getPaddingTop() + y, mPaint); } } } } private int dp2px(int defaultValue) { int scale = (int) getResources().getDisplayMetrics().density; return (int) (defaultValue * scale + 0.5); } }
自定义密码框
最新推荐文章于 2024-09-26 23:53:33 发布