大佬教程收集整理的这篇文章主要介绍了Android自定义View绘制随机生成图片验证码,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
本篇文章讲的是Android自定义view之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义view的开发过程以及一些需要注意的地方。
按照惯例先看看效果图:
一、先总结下自定义view的步骤:
1、自定义view的属性
2、在View的构造方法中获得我们自定义的属性
3、重写onMesure
4、重写onDraw
其中onMesure方法不一定要重写,但大部分情况下还是需要重写的
二、View 的几个构造函数
1、public CustomView(Context context)
―>java代码直接new一个CustomView实例的时候,会调用这个只有一个参数的构造函数;
2、public CustomView(Context context,AttributeSet attrs)
―>在默认的XML布局@L_801_24@中创建的时候调用这个有两个参数的构造函数。AttributeSet类型的参数负责把XML布局@L_801_24@中所自定义的属性通过AttributeSet带入到View内;
3、public CustomView(Context context,AttributeSet attrs,int defStyleAttr)
―>构造函数中第三个参数是默认的Style,这里的默认的Style是指它在当前Application或者Activity所用的Theme中的默认Style,且只有在明确调用的时候才会调用
4、public CustomView(Context context,int defStyleAttr,int defStyleRes)
―>该构造函数是在API21的时候才添加上的
三、下面我们就开始来看看代码啦
1、自定义view的属性,首先在res/values/ 下建立一个attr.xml , 在里面定义我们的需要用到的属性以及声明相对应属性的取值类型
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="text" format="String" /> <attr name="textColor" format="color" /> <attr name="textSize" format="dimension" /> <attr name="bgColor" format="color" /> <declare-styleable name="CustomView"> <attr name="text" /> <attr name="textColor" /> <attr name="textSize" /> <attr name="bgColor" /> </declare-styleable> </resources>
我们定义了字体,字体颜色,字体大小以及字体的背景颜色4个属性,format是值该属性的取值类型,format取值类型总共有10种,包括:String,color,demension,Integer,enum,reference,float,Boolean,fraction和flag。
2、然后在XML布局中声明我们的自定义view
<RelativeLayout xmlns:android="http://scheR_871_11845@as.android.com/apk/res/android" xmlns:custom="http://scheR_871_11845@as.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.per.customview01.view.CustomView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:padding="10dp" custom:bgColor="#FF27FF28" custom:text="J2RdWQG" custom:textColor="#ff0000" custom:textSize="36dp" /> </RelativeLayout>
一定要引入xmlns:custom=”http://scheR_871_11845@as.android.com/apk/res-auto”,Android studio中我们可以使用res-atuo命名空间,就不用在添加自定义view全类名。
/** * 文本 */ private String mText; /** * 文本的颜色 */ privatE int mTextColor; /** * 文本的大小 */ privatE int mTextSize; /** * 文本的背景颜色 */ privatE int mBgCplor; private Rect mBound; private Paint mPaint; public CustomView(Context context) { this(context,null); } public CustomView(Context context,AttributeSet attrs) { this(context,attrs,0); } public CustomView(Context context,int defStyleAttr) { super(context,defStyleAttr); /** * 获得我们所定义的自定义样式属性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomView,defStyleAttr,0); for (int i = 0; i < a.geTindexCount(); i++) { int attr = a.geTindex(i); switch (attr) { case R.styleable.CustomView_text: mText = a.getString(attr); break; case R.styleable.CustomView_textColor: // 默认文本颜色设置为黑色 mTextColor = a.getColor(R.styleable.CustomView_textColor,Color.bLACK); break; case R.styleable.CustomView_bgColor: // 默认文本背景颜色设置为蓝色 mBgCplor = a.getColor(R.styleable.CustomView_bgColor,Color.bLUE); break; case R.styleable.CustomView_textSize: // 默认设置为16sp,TypeValue也可以把sp转化为px mTextSize = a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getresources().getDisplaymetrics())); break; } } a.recycle(); // 获得绘制文本的宽和高 mPaint = new Paint(); mPaint.setTextSize(mTextSizE); mBound = new Rect(); mPaint.getTextBounds(mText,mText.length(),mBound); }
我们重写了3个构造方法,在上面的构造方法中说过默认的布局@L_801_24@调用的是两个参数的构造方法,所以记得让所有的构造方法调用三个参数的构造方法,然后在三个参数的构造方法中获得自定义属性。
一开始一个参数的构造方法和两个参数的构造方法是这样的:
public CustomView(Context context) { super(context); } public CustomView(Context context,AttributeSet attrs) { super(context,attrs); }
有一点要注意的是super应该改成this,然后让一个参数的构造方法引用两个参数的构造方法,两个参数的构造方法引用三个参数的构造方法,代码如下:
4、重写onDraw,onMesure方法
@Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpeC) { super.onMeasure(widthMeasureSpec,heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(mBgCplor); canvas.drawRect(0,getMeasuredWidth(),getMeasuredHeight(),mPaint); mPaint.setColor(mTextColor); canvas.drawText(mText,getWidth() / 2 - mBound.width() / 2,getHeight() / 2 + mBound.height() / 2,mPaint); }
View的绘制流程是从ViewRoot的performTravarsals方法开始的,经过measure、layout和draw三个过程才能最终将一个View绘制出来,其中:
•测量――onMeasure():用来测量View的宽和高来决定View的大小
•布局――onLayout():用来确定View在父容器ViewGroup中的放置位置
•绘制――onDraw():负责将View绘制在屏幕上
来看下此时的效果图
细心的朋友会发现,在上面的布局@L_801_24@中,我们是把宽和高设置为wrap_content的,可是这个效果图怎么看都不是我们想要的,这是因为系统帮我们测量的高度和宽度默认是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,这个是对的。但是除了设置明确的宽度和高度,不管我们设置为WRAP_CONTENT还是MATCH_PARENT,系统帮我们测量的结果就是MATCH_PARENT,所以,当我们设置了WRAP_CONTENT时,我们需要自己进行测量,也就是说我们需要重写onMesure方法
下面是我们重写onMeasure代码:
@Override protected void onMeasure(int widthMeasureSpec,heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heighMode = MeasureSpec.getMode(heightMeasureSpec); int heighSize = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : getPaddingLeft() + getPaddingRight() + mBound.width(),heighMode == MeasureSpec.EXACTLY ? heighSize : getPaddingTop() + getPaddingBottom() + mBound.height()); }
我们再看看效果图:
现在这个是我们想要的结果了吧,回归到主题,今天讲的是自定义view之随机生成图片验证码,现在把自定义view的部分完成了,我把完整的代码贴出来
package com.per.customview01.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import com.per.customview01.R; import java.util.Random; /** * @author: adan * @description: * @projectName: CustomView01 * @date: 2016-06-12 * @time: 10:26 */ public class CustomView extends View { private static final char[] CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; /** * 初始化生成随机数的类 */ private Random mRandom = new Random(); /** * 初始化可变字符串 */ private StringBuffer sb = new StringBuffer(); /** * 文本 */ private String mText; /** * 文本的颜色 */ privatE int mTextColor; /** * 文本的大小 */ privatE int mTextSize; /** * 文本的背景颜色 */ privatE int mBgCplor; private Rect mBound; private Paint mPaint; public CustomView(Context context) { this(context,mBound); this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mText = createCode(); mTextColor = randomColor(); mBgCplor = randomColor(); //View重新调用一次draw过程,以起到界面刷新的作用 posTinvalidate(); } }); } /** * 生成验证码 */ public String createCode() { sb.delete(0,sb.length()); // 使用之前首先清空内容 for (int i = 0; i < 6; i++) { sb.append(CHARS[mRandom.nexTint(CHARs.length)]); } Log.e("生成验证码",sb.toString()); return sb.toString(); } /** * 随机颜色 */ privatE int randomColor() { sb.delete(0,sb.length()); // 使用之前首先清空内容 String haxString; for (int i = 0; i < 3; i++) { haxString = Integer.toHexString(mRandom.nexTint(0xFF)); if (haxString.length() == 1) { haxString = "0" + haxString; } sb.append(haxString); } Log.e("随机颜色","#" + sb.toString()); return Color.parseColor("#" + sb.toString()); } @Override protected void onMeasure(int widthMeasureSpec,heighMode == MeasureSpec.EXACTLY ? heighSize : getPaddingTop() + getPaddingBottom() + mBound.height()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(mBgCplor); canvas.drawRect(0,mPaint); } }
我们添加了一个点击事件,每一次点击View我都让它把生成的验证码和字体颜色以及字体背景颜色打印出来,如下所示:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是大佬教程为你收集整理的Android自定义View绘制随机生成图片验证码全部内容,希望文章能够帮你解决Android自定义View绘制随机生成图片验证码所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。