您的位置:首页 > 其它

自定义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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: