您的位置:首页 > 移动开发 > Android开发

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;
    }
}
效果图:点击可随机产生数字

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息