自定义TextView实现验证码功能

看了鸿洋大神博客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(mText0mText.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(00, 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() / mBound.width() / 2, (getHeight() / 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.stopYmPaint);
        // 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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值