Android拆轮子系列之写验证码控件的方法

前言

先看看效果

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

用到的知识点总结:

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 ); } @Override public void onClick(View v) { //在这里面更新,重新换一套验证码字符 } @Override protected 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);

以上所述是小编给大家介绍的Android拆轮子系列之写验证码控件的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

时间: 2024-09-20 05:17:28

Android拆轮子系列之写验证码控件的方法的相关文章

Android拆轮子系列之写验证码控件的方法_Android

前言 先看看效果 怎么样不错吧?别急下面我就一步一步的教你实现. 用到的知识点总结: 1.Canvas和pint的使用,我们用它画点,线,字 2.View的基本用法 其实做这个东西还是很简单的,总体思路步骤如下: 1.准备一个Canvas. 2.向Canvas里面画几条斜杠. 3.向canvas里面画100个小点. 4.随机生成4个数字,然后画在canvas里面. 其实就是这么简单,没什么深奥的. 开始写编码 1.首先我们要重写View 既然我们要画验证码,那么我们就需要准备画笔(paint)和

版本控制-android加载图片的时候图片控件是黑色的

问题描述 android加载图片的时候图片控件是黑色的 我使用我自己写的ImageView进行加载图片,报出cannot generate texture from bitmap的错误,而且图片控件是黑色的,百度搜了,说是因为设置图片的非硬件加速模式是在api11之后添加的,要进行版本控制,我进行控制了,程序直接停止了,我想问问是不是我写得ImageView有问题?下面是我的ImageView类: public class Imageview extends ImageView implemen

请问android如何实现在一个activity使用按钮控件控制不同的布局文件?

问题描述 请问android如何实现在一个activity使用按钮控件控制不同的布局文件? 如题,比如说在同一个activity下当用户点击第一个按钮之后activity的布局随之换成另一个布局文件~ 解决方案 最简单的办法,重新setContentView 解决方案二: 上面的没错,或者layout写多个布局,控制显示隐藏

jQuery Validate 验证,校验规则写在控件中的具体实例

 本篇文章主要是对jQuery Validate 验证,校验规则写在控件中的具体实例进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 将校验规则写到控件中    代码如下: <script src="../js/jquery.js" type="text/javascript"></script> <script src="../js/jquery.validate.js" type="text/j

android中响应Fragment界面中的控件的问题

问题描述 android中响应Fragment界面中的控件的问题 Fragment界面中 怎么对其中的控件比如按钮添加监听事件?先说好,在onCreateView()跟onActivityCreated()中添加是没有反应的 解决方案 在 fragment中:(点击button弹出toast)@Override public View onCreateView(LayoutInflater inflater ViewGroup container Bundle savedInstanceStat

Android基于widget组件实现物体移动/控件拖动功能示例_Android

本文实例讲述了Android基于widget组件实现物体移动/控件拖动功能.分享给大家供大家参考,具体如下: package com.sky; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickLi

Android自定义View之自定义评价打分控件RatingBar实现自定义星星大小和间距_Android

在Android开发中,我们经常会用到对商家或者商品的评价,运用星星进行打分.然而在Android系统中自带的打分控件,RatingBar特别不好用,间距和大小无法改变.所以,我就自定义了一个特别好用的打分控件.在项目中可以直接使用,特别简单.下面直接上图: 效果图 实现原理 其实就是自定义View继承LinearLayout ,然后里面动态加了五个ImageView. 实现代码,有详细的注释 在attrs中声明的可以在xml中设置的变量 <declare-styleable name="

Android中一个在MainActivity中的控件在OneActivity中怎样获取到

问题描述 Android中一个在MainActivity中的控件在OneActivity中怎样获取到 每点击一次添加按钮 购物车的TextView 更新一次 解决方案 Android-获取view中的一个控件 解决方案二: 有很多种方式,如果单纯获取控件可以通过Layoutinflater获取view,然后获取控件

C#写Activex控件给DELPHI使用时,如果加上事件??

问题描述 需要用C#编写Activex控件,并且在DELPHI6.0环境下使用,ACTIVEX控件的方法在DELPHI中已经可以调用,但是在DELPHI的那个OBJECTINSPECTOR中一直没有显示C#activex里定义的事件,但是项目是需要事件触发的,没辙了...哪位高手写过的给个完整例子可以么?或者详细讲解一下?不胜感谢!! 解决方案 解决方案二:没人理是不是太简单了啊,自己顶一下解决方案三:DELPHI没搞过,,没人不是因为太简单了,,太简单了会有很多人回复的,,要么就是问题太难,要