自定义TextView实现验证码功能
2015-12-29 16:52
387 查看
看了鸿洋大神博客http://blog.csdn.net/lmj623565791/article/details/24252901
决定跟随他的步伐继续深入的完成这个自定义TextView 实现验证码功能:
有图有真相:
自定义View的步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw
1.自定义属性:在values 新建attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="checkText" format="string"></attr>
<attr name="checkTextColor" format="color"></attr>
<attr name="checkTextSize" format="dimension"></attr>
<declare-styleable name="CheckTextView">
<attr name="checkText"/>
<attr name="checkTextColor"/>
<attr name="checkTextSize"/>
</declare-styleable>
</resources>
2.在View的构造方法中获得自定义属性:
private String mText;
private int mColor;
private int mSize;
private Rect mBound;//绘制文本的范围
private Paint mPaint;
private List<PointX> points;//产生直线点的集合
public CheckTextView(Context context) {
this(context,null);
}
public CheckTextView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public CheckTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CheckTextView,defStyleAttr,0);
int n = ta.getIndexCount();
for(int i = 0; i < n ;i++){
int attr = ta.getIndex(i);
switch (attr){
case R.styleable.CheckTextView_checkText:
mText = ta.getString(attr);
break;
case R.styleable.CheckTextView_checkTextColor:
mColor = ta.getColor(attr, Color.BLACK);
break;
case R.styleable.CheckTextView_checkTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mSize = ta.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
ta.recycle();
//获得绘制文本的宽高
mPaint = new Paint();
mPaint.setTextSize(mSize);
mBound = new Rect();
Log.d("gac","textsize:"+mSize);
//获得文本的宽高
mPaint.getTextBounds(mText, 0, mText.length(), mBound);
createLinePoints();
Log.d("gac", "mBound:" + mBound.width() + "," + mBound.height());
//初始化设置点击事件
setTextClickListener();
}
3.重写onMeasure方法:
4.重写onDraw方法
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
Log.d("gac", "getMeasuredWidth:" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight());
randomLines(canvas);
Log.d("gac", "getWidth:" + getWidth() + " getHeight:" + getHeight());
// mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setColor(mColor);
//292 147 屏幕宽高 30 117 textsize 120
//232 87 字体宽高
// x y 参数 字体的最左上角x坐标 左下角y坐标
canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, (getHeight() / 2 + mBound.height() / 2), mPaint);
}
randomLines方法 画出验证码上面的干扰的线条
private void randomLines(Canvas canvas){
for(int i = 0; i < 6; i++){
randomLine(canvas,points.get(i));
}
}
randomLine方法 画出一条线条 线条具有随机性
private void randomLine(Canvas canvas,PointX p){
mPaint.setColor(Color.RED);
float old = mPaint.getStrokeWidth();
//设置线条宽度
mPaint.setStrokeWidth(4.0f);
// Log.d("gac", startX + " " + " " + startY + " " + stopX + " " + stopY);
canvas.drawLine(p.startX, p.startY, p.stopX, p.stopY, mPaint);
// canvas.drawLine(10, 10, 100, 100,mPaint);
//设置回原来线条宽度
mPaint.setStrokeWidth(old);
}
PointX 保存线条的四个点:
private class PointX{
private int startX;
private int startY;
private int stopX;
private int stopY;
public PointX(int startX, int startY, int stopX,int stopY){
this.startX = startX;
this.startY = startY;
this.stopX = stopX;
this.stopY = stopY;
}
}
//产生六条随机线条的点的集合
//初始化时候 调用一次 每次点击textview时候调用 产生新的点的集合
private void createLinePoints(){
points = new ArrayList<PointX>();
for(int i = 0; i < 6; i++){
Random rand = new Random();
int startX = rand.nextInt( mBound.width()-1)+1;
int startY = rand.nextInt(mBound.height()-1)+1;
int stopX = rand.nextInt( mBound.width() - 1)+1;
int stopY = rand.nextInt(mBound.height()-1)+1;
points.add(new PointX(startX,startY,stopX,stopY));
}
}
//初始化的时候给 TextView设置点击事件 每次点击 切换textView的文本
private void setTextClickListener(){
this.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
randomText();
createLinePoints();
postInvalidate();
}
});
}
//随机产生TextView 文本
private void randomText(){
Random random = new Random();
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 4)
{
int randomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = new StringBuffer();
for (Integer i : set)
{
sb.append("" + i);
}
mText = sb.toString();
}
//获取文本 进行验证
public String getCheckText(){
return mText;
}
源码下载地址:https://github.com/gacmy/checkTextView/
决定跟随他的步伐继续深入的完成这个自定义TextView 实现验证码功能:
有图有真相:
自定义View的步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw
1.自定义属性:在values 新建attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="checkText" format="string"></attr>
<attr name="checkTextColor" format="color"></attr>
<attr name="checkTextSize" format="dimension"></attr>
<declare-styleable name="CheckTextView">
<attr name="checkText"/>
<attr name="checkTextColor"/>
<attr name="checkTextSize"/>
</declare-styleable>
</resources>
2.在View的构造方法中获得自定义属性:
private String mText;
private int mColor;
private int mSize;
private Rect mBound;//绘制文本的范围
private Paint mPaint;
private List<PointX> points;//产生直线点的集合
public CheckTextView(Context context) {
this(context,null);
}
public CheckTextView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public CheckTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CheckTextView,defStyleAttr,0);
int n = ta.getIndexCount();
for(int i = 0; i < n ;i++){
int attr = ta.getIndex(i);
switch (attr){
case R.styleable.CheckTextView_checkText:
mText = ta.getString(attr);
break;
case R.styleable.CheckTextView_checkTextColor:
mColor = ta.getColor(attr, Color.BLACK);
break;
case R.styleable.CheckTextView_checkTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mSize = ta.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
ta.recycle();
//获得绘制文本的宽高
mPaint = new Paint();
mPaint.setTextSize(mSize);
mBound = new Rect();
Log.d("gac","textsize:"+mSize);
//获得文本的宽高
mPaint.getTextBounds(mText, 0, mText.length(), mBound);
createLinePoints();
Log.d("gac", "mBound:" + mBound.width() + "," + mBound.height());
//初始化设置点击事件
setTextClickListener();
}
3.重写onMeasure方法:
4.重写onDraw方法
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
Log.d("gac", "getMeasuredWidth:" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight());
randomLines(canvas);
Log.d("gac", "getWidth:" + getWidth() + " getHeight:" + getHeight());
// mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setColor(mColor);
//292 147 屏幕宽高 30 117 textsize 120
//232 87 字体宽高
// x y 参数 字体的最左上角x坐标 左下角y坐标
canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, (getHeight() / 2 + mBound.height() / 2), mPaint);
}
randomLines方法 画出验证码上面的干扰的线条
private void randomLines(Canvas canvas){
for(int i = 0; i < 6; i++){
randomLine(canvas,points.get(i));
}
}
randomLine方法 画出一条线条 线条具有随机性
private void randomLine(Canvas canvas,PointX p){
mPaint.setColor(Color.RED);
float old = mPaint.getStrokeWidth();
//设置线条宽度
mPaint.setStrokeWidth(4.0f);
// Log.d("gac", startX + " " + " " + startY + " " + stopX + " " + stopY);
canvas.drawLine(p.startX, p.startY, p.stopX, p.stopY, mPaint);
// canvas.drawLine(10, 10, 100, 100,mPaint);
//设置回原来线条宽度
mPaint.setStrokeWidth(old);
}
PointX 保存线条的四个点:
private class PointX{
private int startX;
private int startY;
private int stopX;
private int stopY;
public PointX(int startX, int startY, int stopX,int stopY){
this.startX = startX;
this.startY = startY;
this.stopX = stopX;
this.stopY = stopY;
}
}
//产生六条随机线条的点的集合
//初始化时候 调用一次 每次点击textview时候调用 产生新的点的集合
private void createLinePoints(){
points = new ArrayList<PointX>();
for(int i = 0; i < 6; i++){
Random rand = new Random();
int startX = rand.nextInt( mBound.width()-1)+1;
int startY = rand.nextInt(mBound.height()-1)+1;
int stopX = rand.nextInt( mBound.width() - 1)+1;
int stopY = rand.nextInt(mBound.height()-1)+1;
points.add(new PointX(startX,startY,stopX,stopY));
}
}
//初始化的时候给 TextView设置点击事件 每次点击 切换textView的文本
private void setTextClickListener(){
this.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
randomText();
createLinePoints();
postInvalidate();
}
});
}
//随机产生TextView 文本
private void randomText(){
Random random = new Random();
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 4)
{
int randomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = new StringBuffer();
for (Integer i : set)
{
sb.append("" + i);
}
mText = sb.toString();
}
//获取文本 进行验证
public String getCheckText(){
return mText;
}
源码下载地址:https://github.com/gacmy/checkTextView/
相关文章推荐
- 职业规划
- 动态顺序表 与 双向链表的模板类
- Android 编程下的四大组件之服务(Service)
- 关于MYSQL的配置文件my.cnf 一些存放位置和配置说明
- Yii2 rules常用规则
- 监听Dialog的状态 OnDissmiss OnShow
- j48源码学习笔记(三)InfoGainSplitCrit, GainRatioSplitCrit,熵的计算
- 预算及费用控制方案:以“我”为中心,构建企业信息化财务管控体系
- 给tableView设置背景图片
- [Music] Billboard Hot 100 Singles Chart 27th Jun 2015
- MySql获取某天是一年的第几周
- android系统分区
- 属性动画
- MYSQL \ORACLE\SQL 删除主键字段
- 类似微信红包随机分配js方法
- 解决PHP生成UTF-8编码的CSV文件用Excel打开乱码的问题
- 转:没有显示器且IP未知的情况下登录树莓派
- 宿主机SSH登录VirtualBox中的Linux CentOS 7(主宿互访)
- this和super的区别
- 那些年犯过的2(出过的BUG)