Android实现验证码效果

使用自定义View实现验证码的效果可以分以下几步:

a、画出长方形和里面的数字

b、在长方形区域家细线和噪点

c、给此View加监听事件,实现点击时,噪点和细线随数字的变化而变化



核心代码:


/**
  * 文本
  */
 private String mTitleText;
 /**
  * 文本的颜色
  */
 private int mTitleTextColor;
 /**
  * 文本的大小
  */
 private int mTitleTextSize;

 /**
  * 绘制时控制文本绘制的范围
  */
 private Rect mBound;
 private Paint mPaint;

 public CustomTitleView(Context context, AttributeSet attrs)
 {
  this(context, attrs, 0);
 }

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

 /**
  * 获得我自定义的样式属性
  *
  * @param context
  * @param attrs
  * @param defStyle
  */
 public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
 {
  super(context, attrs, defStyle);
  /**
   * 获得我们所定义的自定义样式属性
   */
  TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
  int n = a.getIndexCount();
  for (int i = 0; i < n; i++)
  {
   int attr = a.getIndex(i);
   switch (attr)
   {
   case R.styleable.CustomTitleView_titleText:
    mTitleText = a.getString(attr);
    break;
   case R.styleable.CustomTitleView_titleTextColor:
    // 默认颜色设置为黑色
    mTitleTextColor = a.getColor(attr, Color.BLACK);
    break;
   case R.styleable.CustomTitleView_titleTextSize:
    // 默认设置为16sp,TypeValue也可以把sp转化为px
    mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
      TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
    break;

   }

  }
  a.recycle();

  /**
   * 获得绘制文本的宽和高
   */
  mPaint = new Paint();
  mPaint.setTextSize(mTitleTextSize);
  // mPaint.setColor(mTitleTextColor);
  mBound = new Rect();
  mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);

  this.setOnClickListener(new OnClickListener()
  {

   @Override
   public void onClick(View v)
   {
    mTitleText = randomText();
    postInvalidate();
   }

  });

 }
 private String randomText()
 {
  Random random = new Random();
  Set<Integer> set = new HashSet<Integer>();
  while (set.size() < 4)
  {
   int randomInt = random.nextInt(10);
   set.add(randomInt);
  }
  StringBuffer sb = new StringBuffer();
  for (Integer i : set)
  {
   sb.append("" + i);
  }

  return sb.toString();
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
 {
  // super.onMeasure(widthMeasureSpec, heightMeasureSpec);

  int width = 0;
  int height = 0;

  /**
   * 设置宽度
   */
  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;
  }

  /**
   * 设置高度
   */
  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.YELLOW);
  canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

  mPaint.setColor(mTitleTextColor);
  canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);

  final int height = getHeight();
  final int width = getWidth();
  // 绘制小圆点
  int[] point;
  for (int i = 0; i < 100; i++) {
   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], 2, mPaint);
  }

  int [] line;
  for(int i = 0; i < 100; i ++)
  {
   line = getLine(height, width);
   /**
    * startX:起始端点的X坐标。
    *startY:起始端点的Y坐标。
    *stopX:终止端点的X坐标。
    *stopY:终止端点的Y坐标。
    *paint:绘制直线所使用的画笔。
    */

   mPaint.setStrokeWidth(2.0f);
   canvas.drawLine(line[0], line[1], line[2], line[3], mPaint);
  }
 }

 /**
  * 干扰数字的线
  * @param height
  * @param width
     * @return
     */
 public  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;
 }

 /**
  * 噪点
  * @param height
  * @param width
     * @return
     */

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


运行效果如下:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值