Android自定义类似支付宝密码输入的控件

来源:互联网 发布:手游cfbug软件 编辑:程序博客网 时间:2024/05/16 08:32

前言:感觉自己记忆力不是很好,很多写过的东西容易忘记,所以还是写个博客记录一下,菜鸟一枚,望各位师傅指点。

嘿喂狗,来看我们要实现的效果(如果你说:”开发之前当然看不到效果,看个diao啊“。我只能说:会YY吗【PS:老猿可能觉得此程序比较简单,勿喷哈:)】)

这里写图片描述

接下来,讲讲如何实现,自定义控件一般分为三种:
1、继承已有的控件来实现自定义控件,如本例就需要继承EditText
2、继承一个布局文件实现自定义控件
3、继承view类来实现自定义控件

我们实现的效果为第一种情况,继承现有的控件,本例我们需继承EditText

实现步骤(此步骤为我的习惯而已)
1、根据需求,确定需要自定义的属性(初学者也可不自定义属性,先写死,然后再考虑自定义属性)
2、在res/values/attrs.xml中定义属性
3、新建类,继承EditText,然后–啪啪啪–码功能

首先,思考有哪些东西需要自定义,本例可以自定义的有:边框颜色,边框宽度,圆角弧度,间隔线颜色,间隔线宽度,字体大小,字体颜色,数字个数等。

好,我们先看在attrs中如何自定义属性(name为属性名,format为此属性的值类型)

<resources>    <declare-styleable name="VerifyEditView">        <attr name="VerifyBorderWidth" format="dimension" />        <attr name="VerifyBorderColor" format="color" />        <attr name="VerifyBorderRadius" format="dimension" />        <attr name="VerifyCodeTextSize" format="dimension" />        <attr name="VerifyCodeTextColor" format="color" />        <attr name="VerifyCodeLength" format="integer" />    </declare-styleable></resources>

然后,新建类VerifyEditView

public class VerifyEditView extends EditText {    private int mBorderColor;    private int mBorderWidth;    private int mBorderRadius;    private int mCodeLength;    private int mCodeColor;    private int mCodeSize;    private Paint mPaint;    private int mWidth;    private int mHeight;    private RectF mRectF;    private String mTextContent;    private int mTextLength;    //当不需要使用xml声明或者不需要使用inflate动态加载时候,实现此构造函数即可     public VerifyEditView(Context context) {        this(context,null);    }    //在xml创建但是没有指定style的时候被调用    public VerifyEditView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    //有指定style的时候被调用(注:虽然我将代码写在这地方,但是我并没有指定style,事实上,程序会使用第二个构造函数,只是将第三个参数传0而已)    public VerifyEditView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //获取我们在attrs定义的自定义属性        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.VerifyEditView,defStyleAttr,0);        mBorderColor = a.getColor(R.styleable.VerifyEditView_VerifyBorderColor, Color.BLACK);//第二个参数为默认值,当我们在使用此控件但是没有定义此属性值的时候,会使用此处设置的默认值        mBorderWidth = a.getDimensionPixelSize(R.styleable.VerifyEditView_VerifyBorderWidth, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics()));        mBorderRadius = a.getDimensionPixelSize(R.styleable.VerifyEditView_VerifyBorderRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics()));        mCodeColor = a.getColor(R.styleable.VerifyEditView_VerifyCodeTextColor,Color.BLACK);        mCodeLength = a.getInt(R.styleable.VerifyEditView_VerifyCodeLength,6);        mCodeSize = a.getDimensionPixelSize(R.styleable.VerifyEditView_VerifyCodeTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,24,getResources().getDisplayMetrics()));        a.recycle();        //定义一个Paint,并支持抗锯齿        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    }    //在绘制控件时候会自动调用    @Override    protected void onDraw(Canvas canvas) {        mWidth = getWidth();//获取控件的宽度        mHeight = getHeight();//获取控件的高度        mRectF = new RectF(0,0,mWidth,mHeight);        //绘制圆角矩形边框,但是发现,相对于在xml设置相同参数的shape,此处绘制会有明显的不顺滑,如有知道为什么的,请留言告知,谢谢        //mPaint.setStyle(Paint.Style.STROKE);        //mPaint.setColor(mBorderColor);        //mPaint.setStrokeWidth(mBorderWidth);        //canvas.drawRoundRect(mRectF,mBorderRadius,mBorderRadius,mPaint);        //分割线        float offset = mRectF.width() / mCodeLength;        float lineX;        mPaint.setStrokeWidth(1);        for (int i=1;i<mCodeLength;i++){            lineX = mRectF.left + offset * i;            canvas.drawLine(lineX,0,lineX,mRectF.height(),mPaint);        }        mPaint.setColor(mCodeColor);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setTextSize(mCodeSize);        mPaint.setTextAlign(Paint.Align.CENTER);        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();        float baseLine = (mRectF.bottom + mRectF.top - fontMetrics.bottom - fontMetrics.top)/2;        float codeX;        //更新数字        for (int i=0;i<mTextLength;i++){            codeX = mRectF.left + offset * i + offset / 2;            canvas.drawText(mTextContent.substring(i,i+1),codeX,baseLine,mPaint);        }    }    @Override    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {        super.onTextChanged(text, start, lengthBefore, lengthAfter);        this.mTextContent = text.toString();        this.mTextLength = text.toString().length();        invalidate();//当text改变的时候,重新绘制控件    }}

OK,控件写完了,那看看如何使用

<com.hjy.verify.view.VerifyEditView        android:id="@+id/edtTxtVerify"        android:layout_width="match_parent"        android:layout_height="46dp"        android:layout_marginTop="25dp"        android:layout_marginBottom="15dp"        android:layout_marginLeft="40dp"        android:layout_marginRight="40dp"        android:background="@drawable/verify_border"        android:cursorVisible="false"        android:focusable="true"        android:focusableInTouchMode="true"        android:inputType="number"        android:maxLength="6"        app:VerifyBorderColor="@color/verifyBorderColor"        app:VerifyBorderRadius="10dp"        app:VerifyBorderWidth="1px"        app:VerifyCodeLength="6"        app:VerifyCodeTextColor="@color/verifyTextColor"        app:VerifyCodeTextSize="24sp"/>

drawable目录下的verify_border:

<shape xmlns:android="http://schemas.android.com/apk/res/android">    <corners android:radius="10dp" />    <stroke android:color="@color/verifyBorderColor" android:width="1px" /></shape>

代码:https://github.com/DonnyHe/VerifyEditText

0 0
原创粉丝点击