Android从零开搞系列:自定义View(16)自定义验证码输入框效果
来源:互联网 发布:怎么看淘宝销售排行 编辑:程序博客网 时间:2024/06/04 07:17
转载请注意:http://blog.csdn.net/wjzj000/article/details/75007555
本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
写在前面
本篇博客记录了我的第一个开源库相关内容。效果如下:
源码地址:https://github.com/zhiaixinyang/VerifyCodeView
用法很简单:
compile 'verifycode.com.verifycode:verifycodeview:1.0'
想要出现上图的效果,这么做即可。(具体的属性的注释可以查看GitHub)
<verifycode.com.verifycode.VerifyCodeView android:layout_width="match_parent" android:layout_height="wrap_content" app:verifyCodeLength="5" app:verifyCodeMode="1" app:verifyCodeTextSize="24sp" app:verifyCodeTextColor="@color/colorAccent" />
开始解读源码
接下来就让我们进行对源码来一遍翻云覆雨…
思路:
这里我的思路是直接继承View,一切全部交由自己去绘制。(当然也可以继承自TextView)
如果单看效果,实现起来比较的简单:确定好每个验证码所要显示的位置,然后画边框,绘制数字就ok了。思路我们大体清楚了,接下来让我们一同走进广阔无垠的亚欧大陆。冰雪消融,万物复苏,空气中充满着荷尔蒙的气味,又到了看代码的时间了!
第一步:
最开始肯定是,编写自定义属性:
<declare-styleable name="VerifyCodeView"> <attr name="verifyCodeLength" format="integer" /> <attr name="verifyCodeMode" format="integer" /> <attr name="verifyCodePadding" format="dimension" /> <attr name="verifyCodeBorderColor" format="color" /> <attr name="verifyCodeBorderWidth" format="dimension" /> <attr name="verifyCodeTextSize" format="dimension" /> <attr name="verifyCodeCursorFlashTime" format="integer" /> <attr name="isVerifyCodeCursorEnable" format="boolean" /> <attr name="verifyCodeCursorColor" format="color" /> <attr name="verifyCodeTextColor" format="color" /> </declare-styleable>
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.VerifyCodeView);verifyCodeMode =typedArray.getInteger(R.styleable.VerifyCodeView_verifyCodeMode,0);verifyCodeLength = typedArray.getInteger(R.styleable.VerifyCodeView_verifyCodeLength, 4);isCursorEnable = typedArray.getBoolean(R.styleable.VerifyCodeView_isVerifyCodeCursorEnable, true);cursorFlashTime = typedArray.getInteger(R.styleable.VerifyCodeView_verifyCodeCursorFlashTime, 500);borderWidth = typedArray.getDimensionPixelSize(R.styleable.VerifyCodeView_verifyCodeBorderWidth, dp2px(3));//默认的所有颜色都是黑色的borderColor = typedArray.getColor(R.styleable.VerifyCodeView_verifyCodeBorderColor, Color.BLACK);cursorColor = typedArray.getColor(R.styleable.VerifyCodeView_verifyCodeCursorColor, Color.BLACK);textColor = typedArray.getColor(R.styleable.VerifyCodeView_verifyCodeTextColor,Color.BLACK); textSize=typedArray.getDimensionPixelSize(R.styleable.VerifyCodeView_verifyCodeTextSize,sp2px(16));verifyCodePadding = typedArray.getDimensionPixelSize(R.styleable.VerifyCodeView_verifyCodePadding, dp2px(10));typedArray.recycle();
这个过程就不多做累述了,获取xml中的自定义属性,赋予初始值,都是些套路性的代码。
第二步:
这里我们需要进行输入验证码,而且我们使用的是继承View,因此我们要进行监听输入框。这里我们实现了一个内部类,然后初始化的时候调用
setOnKeyListener(内部类);
class VerifyCodeKeyListener implements OnKeyListener { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { int action = event.getAction(); if (action == KeyEvent.ACTION_DOWN) { //删除操作 if (keyCode == KeyEvent.KEYCODE_DEL) { if (TextUtils.isEmpty(verifyCode[0])) { return true; } String deleteText = delete(); if (verifyCodeListener != null && !TextUtils.isEmpty(deleteText)) { //这里是对外提供的回调,如果使用这实现了回调可以对应进行处理 verifyCodeListener.verifyCodeChange(deleteText); } postInvalidate(); return true; } if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) { /** * 只支持数字 */ if (isInputComplete) { return true; } String addText = add((keyCode - 7) + ""); if (verifyCodeListener != null && !TextUtils.isEmpty(addText)) { //这里是对外提供的回调,如果使用这实现了回调可以对应进行处理 verifyCodeListener.verifyCodeChange(addText); } postInvalidate(); return true; } if (keyCode == KeyEvent.KEYCODE_ENTER) { /** * 确认键 */ if (verifyCodeListener != null) { //这里是对外提供的回调,如果使用这实现了回调可以对应进行处理 verifyCodeListener.keyEnterPress(getVerifyCode(), isInputComplete); } return true; } } return false; } }
回调的代码:
/** * 验证码监听者回调 */ public interface VerifyCodeListener { /** * 输入/删除监听 * * @param changeText 输入/删除的字符 */ void verifyCodeChange(String changeText); /** * 输入完成 */ void verifyCodeComplete(); /** * 确认键后的回调 * * @param verifyCode 验证码 * @param isComplete 是否达到要求位数 */ void keyEnterPress(String verifyCode, boolean isComplete); }
第三步:
第三部便是我们的重头戏,计算位置,绘制内容。
这里主要是onDraw()中的几个方法
/** * 绘制光标 */ private void drawCursor(Canvas canvas, Paint paint) { //光标未显示 && 开启光标 && 输入位数未满 && 获得焦点 if (!isCursorShowing && isCursorEnable && !isInputComplete && hasFocus()) { /** * 起始点x点 = paddingLeft + 一个验证码框大小 / 2 + (一个验证码框大小 + 验证码框间距) * 光标下标 * 起始点y点 = paddingTop + (一个验证码框大小 - 光标大小) / 2 * 终止点x点 = 起始点x * 终止点y点 = 起始点y + 光标高度 */ canvas.drawLine((getPaddingLeft() + textSize / 2) + (textSize + verifyCodePadding) * cursorPosition, getPaddingTop() + (textSize - cursorHeight) / 2, (getPaddingLeft() + textSize / 2) + (textSize + verifyCodePadding) * cursorPosition, getPaddingTop() + (textSize + cursorHeight) / 2, paint); } }
/** * 下划线式的验证码外框 */ private void drawUnderLine(Canvas canvas, Paint paint) { for (int i = 0; i < verifyCodeLength; i++) { /** * 根据验证码位数for循环绘制下划线 * 起始点x点 = paddingLeft + (一个验证码框大小 + 验证码框边距) * i * 起始点y点 = paddingTop + 一个验证码框大小 * 终止点x点 = 起始点x点 + 一个验证码框大小 * 终止点y点 = 起始点y点 */ canvas.drawLine(getPaddingLeft() + (textSize + verifyCodePadding) * i, getPaddingTop() + textSize, getPaddingLeft() + (textSize + verifyCodePadding) * i + textSize, getPaddingTop() + textSize, paint); } }
/** * 圆形的验证码外框 */ private void drawCircle(Canvas canvas, Paint paint) { paint.setColor(borderColor); paint.setStrokeWidth(dp2px(2)); paint.setStyle(Paint.Style.STROKE); for (int i = 0; i < verifyCodeLength; i++) { float startX = getPaddingLeft() + (textSize + verifyCodePadding) * i; float startY = getPaddingTop(); float stopX = getPaddingLeft() + (textSize + verifyCodePadding) * i + textSize; float stopY = getPaddingTop() + textSize; canvas.drawCircle((startX+stopX)/2,(startY+stopY)/2,dp2px(20), paint); } }
尾声
整体思路就是如此,比较的简单。如果有需要的话可以移步GitHub查看源码。
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
- Android从零开搞系列:自定义View(16)自定义验证码输入框效果
- Android自定义View实现滴滴验证码输入框效果
- Android从零开搞系列:自定义View(13)新消息小圆点效果
- Android 自定义View之正方形验证码输入框
- 自定义View-输入验证码
- Android从零开搞系列:自定义View(1)setContent()台前幕后
- Android从零开搞系列:自定义View(8)Canvas解析
- android自定义View基础系列一(点击随机生成验证码效果)
- Android从零开搞系列:自定义View(14)仿天天美剧拖动卡片的效果(上)
- Android从零开搞系列:自定义View(15)仿天天美剧拖动卡片的效果(下)
- android 自定义view实现验证码效果(一)
- Android自定义View(一)(验证码)
- Android 自定义View (验证码)
- 自定义View实现验证码效果
- Android自定义数字验证码输入框
- Android从零开搞系列:自定义View(6)ScrollTo+ScrollBy+Scroller+NestedScrolling机制(上)
- Android从零开搞系列:自定义View(7)ScrollTo+ScrollBy+Scroller+NestedScrolling机制(下)
- Android从零开搞系列:自定义View(9)事件分发+事件拦截(滑动冲突)
- October CMS
- 从SRC RPM编译CentOS内核
- Makefile的基本简单使用 常用的规则
- Mybatis特殊字符处理[L]
- MM模块物料-供应商-PO-表
- Android从零开搞系列:自定义View(16)自定义验证码输入框效果
- transient
- Ubuntu下双网卡配置静态路由上网
- iOS日历视图
- cocos2dx休闲游戏--Fruit & Bird 开发学习(1)
- Spring Boot(3)整合Mybatis
- Python日期处理Arrow包(待完善)
- QSplitter
- CEVA DSP构成