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

自定义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 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();

        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) {

        /**
         * 重写之前先了解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 =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;
    }
}

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值