Android一个自定义验证码的实现
2016-04-11 15:31
369 查看
1、在values文件夹下新建attrs.xml文件,添加属性:
2、写一个类继承View
3、使用
<declare-styleable name="CodeView"> <attr name="count" format="integer"/> <attr name="line" format="integer"/> <attr name="font_color" format="color|reference"/> <attr name="font_size" format="dimension|reference"/> </declare-styleable>
2、写一个类继承View
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; import com.customerview.wuweilong.customerview.R; import java.util.Random; /** * Created by wwl on 2016/4/11. * 验证码 */ public class CodeView extends View{ private int DEFAULT_COUNT = 4;//默认数字个数 private int DEFAULT_LINE = 50;//默认干扰线条数 private int DEFAULT_COLOR = Color.RED;//默认字体颜色 private int DEFAULT_FONT_SIZE = 18;//默认字体大小sp private int count; private int line_count; private int font_color; private int font_size; private Random rmd; private Paint mPaint; private String code; public CodeView(Context context) { this(context,null); } public CodeView(Context context, AttributeSet attrs) { this(context, attrs,0); } public CodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CodeView); font_color = a.getColor(R.styleable.CodeView_font_color,DEFAULT_COLOR); font_size = a.getDimensionPixelSize(R.styleable.CodeView_font_size, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, DEFAULT_FONT_SIZE, getResources().getDisplayMetrics())); count = a.getInt(R.styleable.CodeView_count, DEFAULT_COUNT); line_count = a.getInt(R.styleable.CodeView_line, DEFAULT_LINE); rmd = new Random(); mPaint = new Paint(); code = getCode(); initPaint(); } //获取验证码 private String getCode(){ String code = ""; for (int i = 0 ; i < count; i++){ code += rmd.nextInt(10); } return code; } //初始化paint private void initPaint(){ // mPaint.reset(); mPaint.setAntiAlias(true); mPaint.setColor(font_color); mPaint.setTextSize(font_size); } //计算宽度 private int measureWidth(int widthMeasureSpec){ int mode = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); if (mode == MeasureSpec.EXACTLY){ return width; }else if(mode == MeasureSpec.AT_MOST){ return getPaddingLeft()+getRect().width()+getPaddingRight(); } return 0; } //计算高度 private int measureHeght(int heightMeasureSpec){ int mode = MeasureSpec.getMode(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (mode == MeasureSpec.EXACTLY){ return height; }else if (mode == MeasureSpec.AT_MOST){ return getPaddingTop()+getRect().height()+getPaddingBottom(); } return 0 ; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = measureWidth(widthMeasureSpec); int height = measureHeght(heightMeasureSpec); setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getMeasuredWidth(); int height = getMeasuredHeight(); Rect rect = new Rect(0,0,width,height); //绘制外围矩形框 Rect rect1 = new Rect(rect); rect1.inset(2,2); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(1); mPaint.setColor(0xff00ffff); canvas.drawRect(rect1, mPaint); mPaint.setStyle(Paint.Style.FILL); //绘制随机干扰线 mPaint.setColor(Color.GRAY); for (int i = 0 ; i < line_count;i++){ int startX = rmd.nextInt(width); int startY = rmd.nextInt(height); int stopX = rmd.nextInt(width); int stopY = rmd.nextInt(height); canvas.drawLine(startX,startY,stopX,stopY,mPaint); } //绘制文字 mPaint.setColor(font_color); Rect textRect = getRect(); Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); int x = (width - textRect.width())/2; int y = (int)(height/2+(fontMetrics.descent-fontMetrics.ascent)/2-fontMetrics.descent); canvas.drawText(code,x,y,mPaint); } //获取字体所占的区域 private Rect getRect(){ Rect rect = new Rect(); mPaint.getTextBounds(code,0,code.length(),rect); return rect; } //刷新验证码 public void refresh(){ code = getCode(); invalidate();//重新ondraw } //获取验证码 public String getTheCode(){ return code; } //判断用户输入验证码是否正确 public boolean isRigth(String inputCode){ if (inputCode == null) return false; if (inputCode.equals(code)) return true; return false; } }
3、使用
<com.customerview.wuweilong.customerview.view.CodeView android:id="@+id/codeView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" wwl:count="5" wwl:font_color="#00ff00" wwl:font_size="24sp" wwl:line="50" />
codeView = (CodeView) findViewById(R.id.codeView); refreshBtn = (Button) findViewById(R.id.refresh_btn); refreshBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(CodeViewActivity.this,"上一个验证码是"+codeView.getTheCode(),Toast.LENGTH_SHORT).show(); codeView.refresh(); } }); editText = (EditText) findViewById(R.id.edit_text); editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { String inputCode = editText.getText().toString().trim(); String result; result = codeView.isRigth(inputCode) ? "right" : "false"; Toast.makeText(CodeViewActivity.this, result, Toast.LENGTH_SHORT).show(); return true; } });
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories