android自定義仿微信、支付寶 密碼輸入框

效果圖:
截圖.png
直接上代碼:
/**
 * Description: 密碼 輸入框
 * Created by zouyulong on 2017/7/31.
 */

public class CustomPasswordInputView extends EditText {
    private Context mContext;

    /**
     * 第一個(gè)密碼實(shí)心圓的圓心坐標(biāo)
     */
    private float mFirstCircleX;
    private float mFirstCircleY;

    /**
     * 當(dāng)前輸入的個(gè)數(shù)
     */
    private int mCurInputCount = 0;

    /**
     * 實(shí)心圓的半徑
     */
    private int mCircleRadius = dip2px(getContext(), 5);

    /**
     * view的寬高
     */
    private int mHeight;
    private int mWidth;

    /**
     * 最大輸入位數(shù)
     */
    private int mMaxCount = 6;

    /**
     * 圓的顏色   默認(rèn)BLACK
     */
    private int mCircleColor = Color.BLACK;

    /**
     * 邊線的顏色
     */
    private int mStrokeColor = Color.BLACK;

    /**
     * 分割線的顏色
     */
    private int mDevideLineColor = Color.BLACK;

    /**
     * 描邊的畫筆
     */
    private Paint mStrokePaint;

    /**
     * 分割線開始的坐標(biāo)x
     */
    private int mDivideLineWStartX;

    /**
     * 分割線的寬度
     */
    private int mDivideLineWidth = dip2px(getContext(), 0.5f);

    /**
     * 描邊的矩形
     */
    private RectF mFrameRectF = new RectF();

    /**
     * 矩形邊框的圓角
     */
    private int mRectAngle = 0;

    /**
     * 豎直分割線的畫筆
     */
    private Paint mDivideLinePaint;

    /**
     * 圓的畫筆
     */
    private Paint mCirclePaint;

    /**
     * 密碼輸入完成事件
     */
    private OnPasswordCompleteListener mCompleteListener;

    public CustomPasswordInputView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        getAtt(attrs);
        initPaint();

        this.setCursorVisible(false);
        this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mMaxCount)});

    }

    private void getAtt(AttributeSet attrs) {
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CustomPasswordInputView);
        mMaxCount = typedArray.getInt(R.styleable.CustomPasswordInputView_maxCount, mMaxCount);
        mCircleColor = typedArray.getColor(R.styleable.CustomPasswordInputView_pwdcircleColor, mCircleColor);
        mCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomPasswordInputView_pwdCircleRadius, mCircleRadius);
        mStrokeColor = typedArray.getColor(R.styleable.CustomPasswordInputView_strokeColor, mStrokeColor);
        mDevideLineColor = typedArray.getColor(R.styleable.CustomPasswordInputView_devideLineColor, mDevideLineColor);
        mDivideLineWidth = typedArray.getDimensionPixelSize(R.styleable.CustomPasswordInputView_divideLineWidth, mDivideLineWidth);
        mRectAngle = typedArray.getDimensionPixelOffset(R.styleable.CustomPasswordInputView_rectAngle, mRectAngle);

        typedArray.recycle();
    }

    /**
     * 初始化畫筆
     */
    private void initPaint() {
        mCirclePaint = getPaint(dip2px(getContext(), 5), Paint.Style.FILL, mCircleColor);

        mStrokePaint = getPaint(dip2px(getContext(), 0.5f), Paint.Style.STROKE, mStrokeColor);

        mDivideLinePaint = getPaint(mDivideLineWidth, Paint.Style.FILL, mStrokeColor);
    }

    /**
     * 設(shè)置畫筆
     *
     * @param strokeWidth 畫筆寬度
     * @param style       畫筆風(fēng)格
     * @param color       畫筆顏色
     * @return
     */
    private Paint getPaint(int strokeWidth, Paint.Style style, int color) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(style);
        paint.setColor(color);
        paint.setAntiAlias(true);

        return paint;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight = h;
        mWidth = w;

        mDivideLineWStartX = w / mMaxCount;

        mFirstCircleX = w / mMaxCount / 2;
        mFirstCircleY = h / 2;

        mFrameRectF.set(0, 0, mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //不刪除的畫會(huì)默認(rèn)繪制輸入的文字
//        super.onDraw(canvas);
        drawWeChatBorder(canvas);
        drawPsdCircle(canvas);
    }


    /**
     * 畫微信支付密碼的樣式
     *
     * @param canvas
     */
    private void drawWeChatBorder(Canvas canvas) {

        canvas.drawRoundRect(mFrameRectF, mRectAngle, mRectAngle, mStrokePaint);

        for (int i = 0; i < mMaxCount - 1; i++) {
            canvas.drawLine((i + 1) * mDivideLineWStartX,
                    0,
                    (i + 1) * mDivideLineWStartX,
                    mHeight,
                    mDivideLinePaint);
        }

    }

    /**
     * 畫密碼實(shí)心圓
     *
     * @param canvas
     */
    private void drawPsdCircle(Canvas canvas) {
        for (int i = 0; i < mCurInputCount; i++) {
            canvas.drawCircle(mFirstCircleX + i * 2 * mFirstCircleX,
                    mFirstCircleY,
                    mCircleRadius,
                    mCirclePaint);
        }
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        mCurInputCount = text.toString().length();
        if (mCurInputCount == mMaxCount && mCompleteListener !=null) {
            mCompleteListener.onComplete(getPasswordString());
        }
        invalidate();
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
        //保證光標(biāo)始終在最后
        if (selStart == selEnd) {
            setSelection(getText().length());
        }
    }

    /**
     * 獲取輸入的密碼
     *
     * @return
     */
    public String getPasswordString() {
        return getText().toString().trim();
    }

    /**
     * 密碼輸入完成回調(diào)
     */
    public interface OnPasswordCompleteListener {
        void onComplete(String password);
    }

    public void setOnCompleteListener(OnPasswordCompleteListener mListener) {
        this.mCompleteListener = mListener;
    }

    /**
     * dp轉(zhuǎn)px  自定義事件注意使用dp為單位
     * @param var0
     * @param var1
     * @return
     */
    public static int dip2px(Context var0, float var1) {
        float var2 = var0.getResources().getDisplayMetrics().density;
        return (int)(var1 * var2 + 0.5F);
    }
}

就不做講解了侮繁,每一行代碼都做了詳細(xì)的注解,代碼已經(jīng)上傳到了github上面如孝。

github地址:

https://github.com/zyl409214686/CustomPasswordInputView.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宪哩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子第晰,更是在濱河造成了極大的恐慌锁孟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茁瘦,死亡現(xiàn)場(chǎng)離奇詭異品抽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)腹躁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來南蓬,“玉大人纺非,你說我怎么就攤上這事∽阜剑” “怎么了烧颖?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窄陡。 經(jīng)常有香客問我炕淮,道長,這世上最難降的妖魔是什么跳夭? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任涂圆,我火速辦了婚禮,結(jié)果婚禮上币叹,老公的妹妹穿的比我還像新娘润歉。我一直安慰自己,他們只是感情好颈抚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布踩衩。 她就那樣靜靜地躺著,像睡著了一般贩汉。 火紅的嫁衣襯著肌膚如雪驱富。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天匹舞,我揣著相機(jī)與錄音褐鸥,去河邊找鬼。 笑死赐稽,一個(gè)胖子當(dāng)著我的面吹牛晶疼,可吹牛的內(nèi)容都是我干的酒贬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼翠霍,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼锭吨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寒匙,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤零如,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后锄弱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體考蕾,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年会宪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肖卧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掸鹅,死狀恐怖塞帐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巍沙,我是刑警寧澤葵姥,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站句携,受9級(jí)特大地震影響榔幸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矮嫉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一削咆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蠢笋,春花似錦态辛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至编矾,卻和暖如春熟史,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窄俏。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蹂匹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凹蜈。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓限寞,卻偏偏與公主長得像忍啸,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子履植,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容