Android自定义View入门之简单验证码控件
2017-04-21 10:57
309 查看
自定义View实现步骤:
1、自定义View的属性。
2、在View的构造方法中获得我们自定义的属性。
3、重写onMesure(非必须)。
4、重写onDraw。
新建attrs.xml
<?xml version="1.0"encoding="utf-8"?>
<resources>
<!--customTitle start-->
<attrname="titleText"format="string"/>
<attr name="titleTextColor"format="color"/>
<attr name="titleTextSize"format="dimension"/>
<declare-styleable name="CustomTitleView">
<attr name="titleText"/>
<attr name="titleTextColor"/>
<attr name="titleTextSize"/>
</declare-styleable>
<!--customTitle end-->
</resources>
布局中
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cjf.customview.MainActivity">
<com.cjf.customview.cutomtitleView.CustomTitleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:t
4000
itleText="4396"
android:padding="10dp"
app:titleTextColor="#ff0000"
app:titleTextSize="40sp"
/>
</RelativeLayout>
具体实现代码:
package
com.cjf.customview.cutomtitleView;
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.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import com.cjf.customview.R;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
/**
* Created by chenjifang on 2017/4/21.
*/
public class CustomTitleViewextends
View {
privateString
mTitleText;//文本
private intmTitleColor;//文字颜色
private intmTitleSize;//文字大小
/**
* 绘制时控制文本绘制的范围
*/
privateRect
mBound;
private PaintmPaint;
public CustomTitleView(Context context) {
this(context, null);
}
publicCustomTitleView(Context context,@Nullable
AttributeSet attrs) {
this(context,attrs,0);
}
publicCustomTitleView(Context context,@Nullable
AttributeSet attrs, intdefStyleAttr) {
super(context,attrs,defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomTitleView,defStyleAttr,0);
int n = a.getIndexCount();
for (inti =
0;i < n;i++) {
intattr = a.getIndex(i);
switch (attr) {
caseR.styleable.CustomTitleView_titleText:
mTitleText= a.getString(attr);
break;
case R.styleable.CustomTitleView_titleTextColor:
mTitleColor= a.getColor(attr,Color.BLACK);
break;
case R.styleable.CustomTitleView_titleTextSize:
mTitleSize= (int)
a.getDimension(attr,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();<
13e69
br />
mPaint=
newPaint();
mPaint.setTextSize(mTitleSize);
mBound=
newRect();
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
this.setOnClickListener(newOnClickListener() {
@Override
public voidonClick(View v) {
mTitleText= randomText();
postInvalidate();
}
});
}
privateString
randomText() {
Random random = newRandom();
Set<Integer> set =new
HashSet<Integer>();
while (set.size() <4) {
intrandomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = newStringBuffer();
for (Integer i : set) {
sb.append(""+ i);
}
returnsb.toString();
}
@Override
protected voidonMeasure(intwidthMeasureSpec,
intheightMeasureSpec) {
/**
* 重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用
*/
intwidthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heghtSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
}else
{
mPaint.setTextSize(mTitleSize);
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
float textWidth =mBound.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;
}
if(heightMode == MeasureSpec.EXACTLY)
{
height = heghtSize;
}else
{
mPaint.setTextSize(mTitleSize);
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
float textHeight =mBound.height();
int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
height = desired;
}
setMeasuredDimension(width,height);
}
@Override
protected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
mPaint.setColor(mTitleColor);
//getwidth()获得整个view的宽度
canvas.drawText(mTitleText,getWidth()
/ 2-
mBound.width() /2,getHeight() /
2+
mBound.height() /2,mPaint);
final int height = getHeight();
final int width = getWidth();
int[] point;
Random random =new
Random();
for (inti =
0;i <
50;i++) {
intranColor =
0xff000000| random.nextInt(0x00ffffff);//随机颜色
mPaint.setColor(ranColor);
point = getPoint(height,width);
/**
* drawCircle (float cx, float cy, float radius, Paint paint)
* float cx:圆心的x坐标。
* float cy:圆心的y坐标。
* float radius:圆的半径。
* Paint paint:绘制时所使用的画笔。
*/
canvas.drawCircle(point[0],point[1],3,mPaint);
}
int[] line;
for (inti =
0;i <
5;i++) {
intranColor =
0xff000000| random.nextInt(0x00ffffff);//随机颜色
mPaint.setColor(ranColor);
line = getLine(height,width);
/**
* startX:起始端点的X坐标。
*startY:起始端点的Y坐标。
*stopX:终止端点的X坐标。
*stopY:终止端点的Y坐标。
*paint:绘制直线所使用的画笔。
*/
canvas.drawLine(line[0],line[1],line[2],line[3],mPaint);
}
}
private int[]getLine(intheight,
intwidth) {
int[] tempCheckNum = {0,0,0,0};
for (inti =
0;i <
4;i +=
2) {
tempCheckNum[i] = (int) (Math.random()
* width);
tempCheckNum[i +1] = (int)
(Math.random() * height);
}
returntempCheckNum;
}
private int[]getPoint(intheight,
intwidth) {
int[] tempCheckNum = {0,0,0,0};
tempCheckNum[0] = (int)
(Math.random() * width);
tempCheckNum[1] = (int)
(Math.random() * height);
return tempCheckNum;
}
}
效果图:点击可随机产生数字
1、自定义View的属性。
2、在View的构造方法中获得我们自定义的属性。
3、重写onMesure(非必须)。
4、重写onDraw。
新建attrs.xml
<?xml version="1.0"encoding="utf-8"?>
<resources>
<!--customTitle start-->
<attrname="titleText"format="string"/>
<attr name="titleTextColor"format="color"/>
<attr name="titleTextSize"format="dimension"/>
<declare-styleable name="CustomTitleView">
<attr name="titleText"/>
<attr name="titleTextColor"/>
<attr name="titleTextSize"/>
</declare-styleable>
<!--customTitle end-->
</resources>
布局中
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cjf.customview.MainActivity">
<com.cjf.customview.cutomtitleView.CustomTitleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:t
4000
itleText="4396"
android:padding="10dp"
app:titleTextColor="#ff0000"
app:titleTextSize="40sp"
/>
</RelativeLayout>
具体实现代码:
package
com.cjf.customview.cutomtitleView;
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.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import com.cjf.customview.R;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
/**
* Created by chenjifang on 2017/4/21.
*/
public class CustomTitleViewextends
View {
privateString
mTitleText;//文本
private intmTitleColor;//文字颜色
private intmTitleSize;//文字大小
/**
* 绘制时控制文本绘制的范围
*/
privateRect
mBound;
private PaintmPaint;
public CustomTitleView(Context context) {
this(context, null);
}
publicCustomTitleView(Context context,@Nullable
AttributeSet attrs) {
this(context,attrs,0);
}
publicCustomTitleView(Context context,@Nullable
AttributeSet attrs, intdefStyleAttr) {
super(context,attrs,defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomTitleView,defStyleAttr,0);
int n = a.getIndexCount();
for (inti =
0;i < n;i++) {
intattr = a.getIndex(i);
switch (attr) {
caseR.styleable.CustomTitleView_titleText:
mTitleText= a.getString(attr);
break;
case R.styleable.CustomTitleView_titleTextColor:
mTitleColor= a.getColor(attr,Color.BLACK);
break;
case R.styleable.CustomTitleView_titleTextSize:
mTitleSize= (int)
a.getDimension(attr,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();<
13e69
br />
mPaint=
newPaint();
mPaint.setTextSize(mTitleSize);
mBound=
newRect();
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
this.setOnClickListener(newOnClickListener() {
@Override
public voidonClick(View v) {
mTitleText= randomText();
postInvalidate();
}
});
}
privateString
randomText() {
Random random = newRandom();
Set<Integer> set =new
HashSet<Integer>();
while (set.size() <4) {
intrandomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = newStringBuffer();
for (Integer i : set) {
sb.append(""+ i);
}
returnsb.toString();
}
@Override
protected voidonMeasure(intwidthMeasureSpec,
intheightMeasureSpec) {
/**
* 重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用
*/
intwidthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heghtSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
}else
{
mPaint.setTextSize(mTitleSize);
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
float textWidth =mBound.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;
}
if(heightMode == MeasureSpec.EXACTLY)
{
height = heghtSize;
}else
{
mPaint.setTextSize(mTitleSize);
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
float textHeight =mBound.height();
int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
height = desired;
}
setMeasuredDimension(width,height);
}
@Override
protected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
mPaint.setColor(mTitleColor);
//getwidth()获得整个view的宽度
canvas.drawText(mTitleText,getWidth()
/ 2-
mBound.width() /2,getHeight() /
2+
mBound.height() /2,mPaint);
final int height = getHeight();
final int width = getWidth();
int[] point;
Random random =new
Random();
for (inti =
0;i <
50;i++) {
intranColor =
0xff000000| random.nextInt(0x00ffffff);//随机颜色
mPaint.setColor(ranColor);
point = getPoint(height,width);
/**
* drawCircle (float cx, float cy, float radius, Paint paint)
* float cx:圆心的x坐标。
* float cy:圆心的y坐标。
* float radius:圆的半径。
* Paint paint:绘制时所使用的画笔。
*/
canvas.drawCircle(point[0],point[1],3,mPaint);
}
int[] line;
for (inti =
0;i <
5;i++) {
intranColor =
0xff000000| random.nextInt(0x00ffffff);//随机颜色
mPaint.setColor(ranColor);
line = getLine(height,width);
/**
* startX:起始端点的X坐标。
*startY:起始端点的Y坐标。
*stopX:终止端点的X坐标。
*stopY:终止端点的Y坐标。
*paint:绘制直线所使用的画笔。
*/
canvas.drawLine(line[0],line[1],line[2],line[3],mPaint);
}
}
private int[]getLine(intheight,
intwidth) {
int[] tempCheckNum = {0,0,0,0};
for (inti =
0;i <
4;i +=
2) {
tempCheckNum[i] = (int) (Math.random()
* width);
tempCheckNum[i +1] = (int)
(Math.random() * height);
}
returntempCheckNum;
}
private int[]getPoint(intheight,
intwidth) {
int[] tempCheckNum = {0,0,0,0};
tempCheckNum[0] = (int)
(Math.random() * width);
tempCheckNum[1] = (int)
(Math.random() * height);
return tempCheckNum;
}
}
效果图:点击可随机产生数字
相关文章推荐
- Android自定义View 做个简单的验证码控件
- Android开发笔记之自定义view篇(入门一简单的TextView)
- Android零基础入门第24节:自定义View简单使用
- Android学习摘记——简单的自定义View(组合控件)
- Android学习摘记——简单的自定义View(自绘控件)
- Android自定义View 简单实现多图片选择控件
- Android零基础入门第24节:自定义View简单使用
- Android零基础入门第24节:自定义View简单使用
- Android自定义View 简单实现多图片选择控件
- Android笔记--简单的自定义View之自绘控件
- Android自定义View--验证码控件
- Android零基础入门第24节:自定义View简单使用
- Android自定义View 简单实现多图片选择控件
- Android 自定义组合控件View
- android之视频播放控件VideoView简单应用
- Android高手进阶教程(二十七)之---基于ViewFlipper实现的自定义新手指引控件.
- Android自定义View 自定义组合控件
- iOS开发入门之UIPickerView控件的简单使用
- Android高手进阶教程(二十七)之---基于ViewFlipper实现的自定义新手指引控件.
- Android入门/TextView控件(四)