自定义密码框

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值