Android自定義View入門之簡單驗證碼控件

自定義View實現步驟:

1、自定義View的屬性。

2、在View的構造方法中獲得我們自定義的屬性。

3、重寫onMesure(非必須)。

4、重寫onDraw。

新建attrs.xml

<?xml version="1.0"encoding="utf-8"?>
<resources>

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

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

_/**

  • 重寫之前先了解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;
}
}

效果圖:點擊可隨機產生數字

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容