Android自定义View入门之简单验证码控件

来源:互联网 发布:淘宝模特拍照 编辑:程序博客网 时间:2024/06/06 12:20

自定义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:titleText="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 CustomTitleViewextendsView {
    privateStringmTitleText;//文本
    private intmTitleColor;//文字颜色
    private intmTitleSize;//文字大小

    /**
     * 绘制时控制文本绘制的范围
     */
    
privateRectmBound;
    private PaintmPaint;

    public CustomTitleView(Context context) {
        this(context, null);
    }

    publicCustomTitleView(Context context,@NullableAttributeSet attrs) {
        this(context,attrs,0);
    }

    publicCustomTitleView(Context context,@NullableAttributeSet 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();

        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();
            }
        });
    }

    privateStringrandomText() {
        Random random = newRandom();
        Set<Integer> set =newHashSet<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) {

        /**
         * 重写之前先了解MeasureSpecspecMode,一共三种类型:
         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 =newRandom();

        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;
    }
}

效果图:点击可随机产生数字


0 0
原创粉丝点击