您的位置:首页 > 移动开发 > Android开发

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

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

嘿喂狗,来看我们要实现的效果(如果你说:”开发之前当然看不到效果,看个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>
1
2
3
4
5
6
7
8
9
10

然后,新建类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改变的时候,重新绘制控件
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

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"/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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>
1
2
3
4

代码:https://github.com/DonnyHe/VerifyEditText
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: