拆轮子系列之教你一步步写验证码控件

前言

先看看效果

怎么样不错吧?别急下面我就一步一步的教你实现。

用到的知识点总结:

1.Canvas和pint的使用,我们用它画点,线,字
2.View的基本用法

其实做这个东西还是很简单的,总体思路步骤如下:

1.准备一个Canvas。
2.向Canvas里面画几条斜杠。
3.向canvas里面画100个小点。
4.随机生成4个数字,然后画在canvas里面。

其实就是这么简单,没什么深奥的。

开始写编码

1.首先我们要重写View

既然我们要画验证码,那么我们就需要准备画笔(paint)和画板(canvas)代码如下:

/*** Created by YuYuanDa on 2016-10-10.*/public class CheckView extends View implements View.OnClickListener{private Context mContext;private Paint mPaint ; // 画笔public CheckView(Context context, AttributeSet attrs) {super(context, attrs);mContext = context;initPaint();//设置点击时间,当自身收到点击应该更新数字(即重新换验证码数字)setOnClickListener(this);}/*** 初始化paint(画笔)*/private void initPaint(){mPaint = new Paint();mPaint.setAntiAlias(true);//加上抗锯齿mPaint.setTextSize(Config.TEXT_SIZE);//设置字体大小mPaint.setStrokeWidth(3);线宽mPaint.setColor(Config.TEXTCOLOR);//设置字体颜色颜色//设置粗体的字体Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);mPaint.setTypeface( font );}@Overridepublic void onClick(View v) {//在这里面更新,重新换一套验证码字符}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(Config.COLOR);//先画一个背景颜色}
}/*** 配置字段*/class Config{// 点数设置public static final int POINT_NUM = 100;// 线段数设置public static final int LINE_NUM = 2;//设置验证码背景颜色public static final int COLOR = Color.rgb(247,230,220);//随机字符长度长度public static int TEXT_LENGTH = 4;//设置验证码字体大小public static int TEXT_SIZE = 40;//验证码字体颜色public static final int TEXTCOLOR = Color.rgb(255,101,1);
}

好了,上面的代码中,我们自定义一个CheckView类,并准备了以下材料:

1.为了更新数据我们设置了点击事件setOnClickListener(this);,
2.Config类是为我们准备配置信息,
3.new 出一支paint(画笔),并添加相关参数。
4.准备了画板canvas(在ondraw()方法中),下面我们将在ondraw()方法中画东西了。

2.接下来我们开始画线、点、字。

画线代码如下:

private void drawLine(Canvas canvas){for (int i = 0; i < Config.LINE_NUM; i++) {//根据LINE_NUM画线的数量,你可以自己配置//划线int[] line = getLine(getHeight(), getWidth());canvas.drawLine(line[0], line[1], line[2], line[3], mPaint);}
}public static int[] getLine(int height, int width) {int[] tempCheckNum = {0, 0, 0, 0};for (int i = 0; i < 4; i += 2) {tempCheckNum[i] = (int) (Math.random() * width);tempCheckNum[i + 1] = (int) (Math.random() * height);}return tempCheckNum;
}

下面我们来讲一下canvas.drawLine()方法。先看看源码:

public void drawLine (float startX, float startY, float stopX, float stopY, Paint paint){
}参数说明:
startX:起始端点的X坐标。
startY:起始端点的Y坐标。
stopX:终止端点的X坐标。
stopY:终止端点的Y坐标。
paint:绘制直线所使用的画笔

看到没,其实画线就需要paint和2个起始点。在getline()方法中,for循环其实就循环了2次,
math.random()取值范围是:0.0~1.0 ,所以可以看出,Math.random() * width/heigth随机的在view中取4个点作为2个点的取值,然后 canvas.drawLine()画出来。

画点代码如下:

private void drawCircle(Canvas canvas){// 绘制小圆点int[] point;for (int i = 0; i < Config.POINT_NUM; i++) {//根据POINT_NUM画点的数量,你可以自己配置//画点point = getPoint(getHeight(), getWidth());canvas.drawCircle(point[0], point[1], 1, mPaint);}
}
/*** 随机产生点的圆心点坐标* @param height 传入CheckView的高度值* @param width  传入CheckView的宽度值* @return*/
public static int[] getPoint(int height, int width) {int[] tempCheckNum = {0, 0, 0, 0};tempCheckNum[0] = (int) (Math.random() * width);tempCheckNum[1] = (int) (Math.random() * height);return tempCheckNum;
}

下面我们来讲一下canvas.drawCircle()方法

基本语法
public void drawCircle (float cx, float cy, float radius, Paint paint)
参数说明
cx:圆心的x坐标。
cy:圆心的y坐标。
radius:圆的半径。
paint:绘制时所使用的画笔。

看了上面的基本语法,大家应该明白了,画圆只需要圆心,半径和paint就行。在getPoint()方法中,我们依旧利用Math.random() * width/height方法在View中随机的取2个点作为圆心。

画文字代码如下:

下面我们就来讲最后一步画文字。这个比较麻烦一点,我们一步步来看,首先画文字需要准备以下东西:

1.取4位数字码,这个好说用Math.random()*10即可
2.画每个文字时的Y坐标怎么取值(你得控制着Y坐标,如果画view外面去,就尴尬了)
3.每个文字间得有相应的间隔(即画每个文字时的X坐标)

我一个一个实现:

取4位数字码:

/*** 产生随机数字*/
public static int[] getCheckNum() {int[] tempCheckNum = new int[Config.TEXT_LENGTH];//TEXT_LENGTH是产生几位数字for (int i = 0; i < Config.TEXT_LENGTH; i++) {tempCheckNum[i] = (int) (Math.random() * 10);//我不说你也明白了吧}return tempCheckNum;//产生4个数放在数组中返回
}

控制Y坐标:

/*** 计算验证码的绘制y点位置* @param height 传入CheckView的高度值* @return*/
public static int getYPos(int height) {int tempPositoin = (int) (Math.random() * height);//不能让它画的太靠上,如果Y坐标<Config.TEXT_SIZE的时候,画出的字就会被遮盖if (tempPositoin < Config.TEXT_SIZE) {tempPositoin += Config.TEXT_SIZE;}else if (tempPositoin > (height-Config.TEXT_SIZE)) {//当然也不能画的太靠下tempPositoin -= Config.TEXT_SIZE;}   return tempPositoin;
}

控制每个文字时的X坐标

看上图,我们把View平分成5分,那么第一个字的X坐标是:getWidth()/5;第二个字的X坐标是getWidth()/5+getWidth()/5;以此类推,这样是不是这4个字就平分在这个View中?好了,好了开始写代码,如下:

 private void drawNum(Canvas canvas){int dx = getWidth() / 5;for (int i = 0; i < 4; i++) {//绘制验证控件上的文本canvas.drawText("" + checkNum[i], dx, getPositon(getHeight()), mPaint);dx += getWidth() / 5;}
}

我们来讲解一下canvas.drawText()方法的基本用法:

drawText(String text, float x, floaty, Paint paint)
参数一:String类型的文本,
参数二:x坐标,
参数三:y坐标,
参数四:Paint对象。

3.点击刷新问题

恭喜大家看到这里,我们还剩下最后一个问题了,如何点击刷新UI?简单,在onclick()方法中重新刷新验证码和UI即可,代码如下:

@Override
public void onClick(View v) {checkNum = CheckUtil.getCheckNum();//checkNum付初值//在这里面更新,重新换一套验证码字符invalidate();
}

4.最后封魔

好了讲到这里,我们接近尾声了,这个代码看起来非常乱,所以,我们需要写一个工具类,将以下这几个方法用工具类CheckView封装起来大工告成:

public  int[] getCheckNum();
public  int[] getLinePos(int height, int width) ;
public  int[] getCirclePoint(int height, int width);
public  int getPositon(int height);

结尾

最后奉送上CheckView的代码。在技术上,我依旧是个小渣渣,加油!勉励自己!

拆轮子系列之教你一步步写验证码控件相关推荐

  1. 拆轮子系列--RxJava理解(一)--Map解析

    本系列文章如下: 拆轮子系列--RxJava前奏篇 拆轮子系列--RxJava理解(一)--Map解析 拆轮子系列--RxJava理解(二)--subscribeOn 拆轮子系列--RxJava理解( ...

  2. 拆轮子系列--RxJava理解(三)--observeOn

    本系列文章如下: 拆轮子系列--RxJava前奏篇 拆轮子系列--RxJava理解(一)--Map解析 拆轮子系列--RxJava理解(二)--subscribeOn 拆轮子系列--RxJava理解( ...

  3. zw版【转发·台湾nvp系列Delphi例程】.NET调用HALCON COM控件内存释放模式

    zw版[转发·台湾nvp系列Delphi例程].NET调用HALCON COM控件内存释放模式 ------------------------------------ 方法一 : Imports S ...

  4. 为触屏手机而设计系列1—拇指操作的热区死角与控件尺寸

    Part 1 研究背景 1.1 触屏手机界面设计的背景与挑战 挑战1:发展时间短,国内外的研究都尚处在探索阶段,充满未知和不确定. 触屏技术最早被应用到手机上要追溯到1999年(motorola A6 ...

  5. 教你如何用VB做控件*.ocx

    教你如何用VB做控件*.ocx 一个控件有很多事件如:Click.MouseDown.MouseUp.MouseMove等.要触发这些事件都需要你加入代码.在控件的声明处加入Public Event ...

  6. 深入学习SAP UI5框架代码系列之八:谈谈 SAP UI5 的视图控件 ID,以及 SAP UI5 视图和 Angular 视图的异同

    今天是 2021 年 4 月 27 日,周二,SAP 全球心理健康日.SAP 全球的员工,今天放假一天. 这不,早在上周五,我所在的 SAP Spartacus 开发团队的开发经理,就贴心地在 Sla ...

  7. Web Client Software Factory系列(4):数据绑定和ObjectContainerDataSource控件

    概述 在Web Client Software Factory系列(3):View-Presenter模式中提到,表示器包含了响应用户事件逻辑以及一些View的状态等,在Web Client Soft ...

  8. 一步一步学Silverlight 2系列(8):使用样式封装控件观感

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  9. 读书印记 - 《文案创作完全手册:文案大师教你一步步写出销售力》

    在互联网时代再看这本书好像不合时宜,但实际未必如此.这本书凝聚了作者作为自由文案写手的多年经验,无论广告形式如何变化里面的部分规则还是相同的:而且其中也根据互联网的特点补充了网络文案.电子邮件等章节. ...

最新文章

  1. dropout是什么?为什么dropout管用?测试集上是否需要使用dropout?说明为什么神经网络中的dropout可以作为正则化?
  2. Java8 新特性之流式数据处理(转)
  3. python代码大全和用法用量_Python numpy.stack()用法及代码示例
  4. 从单体应用到微服务架构演化
  5. filter的原理(转)
  6. iOS之“支付宝支付”开发流程
  7. Redis学习之单机数据库(二)
  8. golang 标准库间依赖的可视化展示
  9. 动态页面技术(EL/JSTL)
  10. 设计灵感|时尚潮流品牌如何通过网页设计呈现
  11. 变压器的分类_变压器的作用
  12. 财富智慧 幸福人生——《菁英财商训练营》首场活动在深圳龙岗文博宫举行
  13. Linux文件编程常用函数详解——read()和write()函数
  14. html获取当前网页ip和端口,js获取当前访问者的IP地址和所属地市代码
  15. 算法基础—数据结构—双链表
  16. nginx 使用配置解释
  17. 19071 递归实现指数型枚举
  18. Esxi5.5添加4T报错的问题
  19. 记一次nginx配置自定义错误页面的麻瓜经历
  20. Linux:进程管理 | 进程创建 | 进程终止 | 进程等待 | 进程替换

热门文章

  1. 这一幕发生在:70、80、90后同坐一个办公室之后..
  2. win10系统与win7系统双系统怎么设置默认启动系统
  3. 996.ICU-加最狠的班,住最贵的医院
  4. Windows Live Writer离线博客工具使用教程(适用于博客园、CSDN、51CTO等等博客)
  5. ZooKeeper 集群
  6. Angry Birds和广告系统泄露个人信息——FireEye对Angry Birds的分析
  7. android EditText取消焦点且退出软键盘
  8. java https http 区别_关于HTTP和HTTPS的区别
  9. 各地软件行业协会通讯录
  10. 学java比较好的网站——HOW2J。