这篇文章主要介绍了 Android 拆轮子系列之写验证码控件的方法的, 涉及到 Canvas 和 pint 的使用和 View 的基本用法等相关知识点,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
前言
先看看效果
怎么样不错吧?别急下面我就一步一步的教你实现。
用到的知识点总结:
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 拆轮子系列之写验证码控件的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 PHPERZ 网站的支持!
来源: http://www.phperz.com/article/17/0316/301146.html