欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義控件深入學(xué)習(xí) Android生成隨機(jī)驗(yàn)證碼

 更新時(shí)間:2016年01月29日 11:48:35   作者:mmsx  
這篇文章主要再次為大家介紹了Android自定義控件,以及針對(duì)自定義view學(xué)習(xí),實(shí)戰(zhàn)演練了Android生成隨機(jī)驗(yàn)證碼的詳細(xì)過程,感興趣的小伙伴們可以參考一下

在上一篇的文章中介紹了自定義控件的屬性,詳情見《詳解Android自定義控件屬性TypedArray以及attrs》。那么在這基礎(chǔ)上實(shí)現(xiàn)隨機(jī)驗(yàn)證碼生成,里面的代碼是自定義控件以及涉及到自定義view繪畫。
1、先看實(shí)現(xiàn)的效果圖


看到這個(gè)效果圖是不是感覺還可以。那么就看看源碼吧。
2、attr文件

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
 
 <attr name="titleText" format="string" /> 
 <attr name="titleTextColor" format="color" /> 
 <attr name="titleTextSize" format="dimension" /> 
 
 <declare-styleable name="AuthCodeView"> 
  <attr name="titleText" /> 
  <attr name="titleTextColor" /> 
  <attr name="titleTextSize" /> 
 </declare-styleable> 
 
</resources> 

3、布局layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 xmlns:authcodeview="http://schemas.android.com/apk/res/com.example.authcodeview" 
 android:id="@+id/LinearLayout1" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:orientation="vertical" > 
 
 <LinearLayout 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" > 
 
  <com.example.authcodeview.view.AuthCodeView 
   android:id="@+id/AuthCodeView" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:padding="10dp" 
   authcodeview:titleText="3712" 
   authcodeview:titleTextColor="#00ffff" 
   authcodeview:titleTextSize="40sp" /> 
 
  <TextView 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="點(diǎn)擊驗(yàn)證碼,換一張" /> 
 </LinearLayout> 
 
 <LinearLayout 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" > 
 
  <TextView 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="輸入驗(yàn)證碼" /> 
 
  <EditText 
   android:id="@+id/editText1" 
   android:layout_width="match_parent" 
   android:layout_height="wrap_content" 
   android:ems="10" 
   android:inputType="number" > 
 
   <requestFocus /> 
  </EditText> 
 </LinearLayout> 
 
 <Button 
  android:id="@+id/button1" 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" 
  android:text="驗(yàn)證" /> 
 
</LinearLayout> 

4、自定義AuthCodeView.class
繼承View,重寫了

onMeasure(int widthMeasureSpec, int heightMeasureSpec)

onDraw(Canvas canvas)方法。
看代碼,有詳細(xì)注釋了。

package com.example.authcodeview.view; 
 
import java.util.Random; 
 
import com.example.authcodeview.R; 
 
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.util.AttributeSet; 
import android.util.TypedValue; 
import android.view.View; 
 
public class AuthCodeView extends View 
{ 
 // 點(diǎn)數(shù)設(shè)置 
 public static final int POINT_NUM = 100; 
 // 線段數(shù)設(shè)置 
 public static final int LINE_NUM = 2; 
 //文本 
 private String mTitleText; 
 // 文本的顏色 
 private int mTitleTextColor; 
 // 文本的大小 
 private int mTitleTextSize; 
  
 String[] mCheckNum = new String[4]; 
 Random random = new Random(); 
  
 //繪制時(shí)控制文本繪制的范圍 
 private Rect mBound; 
 private Paint mPaint; 
 
 public AuthCodeView(Context context, AttributeSet attrs) 
 { 
  this(context, attrs, 0); 
 } 
 
 public AuthCodeView(Context context) 
 { 
  this(context, null); 
 } 
 
 /** 
  * 獲得我自定義的樣式屬性 
  * 
  * @param context 
  * @param attrs 
  * @param defStyle 
  */ 
 public AuthCodeView(Context context, AttributeSet attrs, int defStyle) 
 { 
  super(context, attrs, defStyle); 
  /** 
   * 獲得我們所定義的自定義樣式屬性 
   */ 
  TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AuthCodeView, defStyle, 0); 
   
  //獲取在attr文件下,名字為AuthCodeView的declare-styleable屬性有幾個(gè) 
  int n = a.getIndexCount(); 
  for (int i = 0; i < n; i++) 
  { 
   int attr = a.getIndex(i); 
   switch (attr) 
   { 
   //這個(gè)屬性可以不要,因?yàn)槎际请S機(jī)產(chǎn)生 
   case R.styleable.AuthCodeView_titleText: 
    mTitleText = a.getString(attr); 
    break; 
   case R.styleable.AuthCodeView_titleTextColor: 
    // 默認(rèn)顏色設(shè)置為黑色 
    mTitleTextColor = a.getColor(attr, Color.BLACK); 
    break; 
   case R.styleable.AuthCodeView_titleTextSize: 
    // 默認(rèn)設(shè)置為16sp,TypeValue也可以把sp轉(zhuǎn)化為px 
    mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( 
      TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); 
    break; 
 
   } 
 
  } 
  a.recycle(); 
   
  mTitleText = randomText(); 
 
  /** 
   * 獲得繪制文本的寬和高 
   */ 
  mPaint = new Paint(); 
  mPaint.setTextSize(mTitleTextSize); 
  mBound = new Rect(); 
  mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound); 
 
  this.setOnClickListener(new OnClickListener() 
  { 
 
   @Override 
   public void onClick(View v) 
   { 
    mTitleText = randomText(); 
    postInvalidate(); 
   } 
 
  }); 
 
 } 
  
 //隨機(jī)產(chǎn)生驗(yàn)證碼 
 private String randomText() 
 { 
  StringBuffer sbReturn = new StringBuffer(); 
  for (int i = 0; i < 4; i++) { 
   StringBuffer sb = new StringBuffer(); 
   int randomInt = random.nextInt(10); 
   mCheckNum[i] = sb.append(randomInt).toString(); 
   sbReturn.append(randomInt); 
  } 
   
  return sbReturn.toString(); 
 } 
  
 //獲取驗(yàn)證碼 
 public String getAuthCode() { 
  return mTitleText; 
 } 
 
 //重寫這個(gè)方法,設(shè)置自定義view控件的大小 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
 { 
  // super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 
  int width = 0; 
  int height = 0; 
 
  /** 
   * 設(shè)置寬度 
   */ 
  int specMode = MeasureSpec.getMode(widthMeasureSpec); 
  int specSize = MeasureSpec.getSize(widthMeasureSpec); 
  switch (specMode) 
  { 
  case MeasureSpec.EXACTLY:// 明確指定了 
   width = getPaddingLeft() + getPaddingRight() + specSize; 
   break; 
  case MeasureSpec.AT_MOST:// 一般為WARP_CONTENT 
   width = getPaddingLeft() + getPaddingRight() + mBound.width(); 
   break; 
  } 
 
  /** 
   * 設(shè)置高度 
   */ 
  specMode = MeasureSpec.getMode(heightMeasureSpec); 
  specSize = MeasureSpec.getSize(heightMeasureSpec); 
  switch (specMode) 
  { 
  case MeasureSpec.EXACTLY:// 明確指定了 
   height = getPaddingTop() + getPaddingBottom() + specSize; 
   break; 
  case MeasureSpec.AT_MOST:// 一般為WARP_CONTENT 
   height = getPaddingTop() + getPaddingBottom() + mBound.height(); 
   break; 
  } 
 
  setMeasuredDimension(width, height); 
 
 } 
 
 @Override 
 protected void onDraw(Canvas canvas) 
 { 
  //畫背景顏色 
  mPaint.setColor(Color.BLUE); 
  canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); 
   
  //劃線 
  mPaint.setColor(mTitleTextColor); 
  int [] line; 
  for(int i = 0; i < LINE_NUM; i ++) 
  { 
   //設(shè)置線寬 
   mPaint.setStrokeWidth(5); 
   line = getLine(getMeasuredHeight(), getMeasuredWidth()); 
   canvas.drawLine(line[0], line[1], line[2], line[3], mPaint); 
  } 
   
  // 繪制小圓點(diǎn) 
  int [] point; 
  int randomInt; 
  for(int i = 0; i < POINT_NUM; i ++)  
  { 
   //隨機(jī)獲取點(diǎn)的大小 
   randomInt = random.nextInt(5); 
   point = getPoint(getMeasuredHeight(), getMeasuredWidth()); 
   canvas.drawCircle(point[0], point[1], randomInt, mPaint); 
  } 
 
  //繪制驗(yàn)證控件上的文本 
  int dx = 20; 
  for(int i = 0; i < 4; i ++){ 
   canvas.drawText("" + mCheckNum[i],dx, getHeight() / 2 + getPositon(mBound.height() / 2), mPaint); 
   dx += (getWidth() / 2 - mBound.width() / 2) + i / 5 + 20; 
  } 
//  canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint); 
 } 
  
 //計(jì)算驗(yàn)證碼的繪制y點(diǎn)位置 
 private int getPositon(int height) { 
  int tempPositoin = (int) (Math.random() * height); 
  if (tempPositoin < 20) { 
   tempPositoin += 20; 
  } 
  return tempPositoin; 
 } 
  
 // 隨機(jī)產(chǎn)生點(diǎn)的圓心點(diǎn)坐標(biāo) 
 public static int[] getPoint(int height, int width) { 
  int[] tempCheckNum = { 0, 0, 0, 0 }; 
  tempCheckNum[0] = (int) (Math.random() * width); 
  tempCheckNum[1] = (int) (Math.random() * height); 
  return tempCheckNum; 
 } 
  
 //隨機(jī)產(chǎn)生劃線的起始點(diǎn)坐標(biāo)和結(jié)束點(diǎn)坐標(biāo) 
 public static int[] getLine(int height, int width) { 
  int[] tempCheckNum = { 0, 0, 0, 0 }; 
  for (int i = 0; i < 4; i += 2) { 
   tempCheckNum[i] = (int) (Math.random() * width); 
   tempCheckNum[i + 1] = (int) (Math.random() * height); 
  } 
  return tempCheckNum; 
 } 
} 

5、在MainActivity中怎么使用這個(gè)自定義AuthCodeView
package com.example.authcodeview; 
 
import com.example.authcodeview.view.AuthCodeView; 
import android.os.Bundle; 
import android.app.Activity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.EditText; 
import android.widget.Toast; 
 
public class MainActivity extends Activity implements OnClickListener 
{ 
 
 private AuthCodeView mauthCodeView; 
 @Override 
 protected void onCreate(Bundle savedInstanceState) 
 { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
   
  initUI(); 
 } 
 
 private void initUI() { 
  mauthCodeView = (AuthCodeView)findViewById(R.id.AuthCodeView); 
  findViewById(R.id.button1).setOnClickListener(this); 
 } 
 
 @Override 
 public void onClick(View v) { 
  switch (v.getId()) { 
  case R.id.button1: 
   EditText editText = (EditText)findViewById(R.id.editText1); 
   String codeString = editText.getText().toString().trim(); 
   if (codeString.equals(mauthCodeView.getAuthCode())) { 
    Toast.makeText(this, "驗(yàn)證碼驗(yàn)證正確!", Toast.LENGTH_LONG).show(); 
   }else { 
    Toast.makeText(this, "驗(yàn)證碼錯(cuò)誤!", Toast.LENGTH_LONG).show(); 
   } 
   break; 
 
  default: 
   break; 
  } 
   
 } 
 
 
} 

源碼下載:Android生成隨機(jī)驗(yàn)證碼Demo

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

最新評(píng)論