android自定义View基础系列一(点击随机生成验证码效果)
来源:互联网 发布:聊城关键词优化 编辑:程序博客网 时间:2024/06/13 07:23
前言:
写了几篇博文,说实话自己很不满意,都觉得很空洞,写的也不是很好,只能硬着头皮继续写,写多了希望能好些,这一系列都是基础+练手系列,大神无视,不管怎么样,希望能对大家有点帮助吧。
本系列主要是介绍一些使用绘制view方式来自定义view实现的一些效果,很多是我之前学别人实现的一些效果,作为基础入门篇。
概要:
记得之前学习hy大神的博文,大神说自定义VIew三大步骤:
1)自定义View的属性;
2)在构造方法中获取到属性;
3)重写onMeasure,onDraw,onLayout方法。
我一直秉承着大神的意志学习前进着,觉得还是蛮有用的,至少不会无从下手。本文将实现一个类似点击随机生成验证码的效果,比较简单。效果如图:
正文:
首先分析下我们会用到的属性,这里需要用到按钮背景色,文字颜色,字体大小。现在我们开始自定义属性,在values文件夹下创建一个attrs.xml文件,在里面定义我们的属性,声明我们的样式。
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyViewAttrs"> <attr name="bgColor" format="color">#dddddd</attr> <attr name="textColor" format="color">#ff0000</attr> <attr name="textSize" format="dimension">30</attr> </declare-styleable></resources>这里format是取值类型。有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag。
现在声明自定义View,在布局文件中引入自定义View。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.example.liujibin.testmyview1" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.liujibin.testmyview1.MainActivity"> <com.example.liujibin.testmyview1.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" /></RelativeLayout>在声明的View中重写构造函数,这里因为要获取属性,所以我们设置默认调用含三个参数的构造函数。
public class MyView extends View { //背景色 private int bgColor; //文字色 private int textColor; //文字大小 private int textSize; public MyView(Context context) { this(context,null); } public MyView(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyViewAttrs,defStyleAttr,0); bgColor = ta.getColor(R.styleable.MyViewAttrs_bgColor, Color.BLACK); textColor = ta.getColor(R.styleable.MyViewAttrs_textColor,Color.WHITE); textSize = ta.getDimensionPixelSize(R.styleable.MyViewAttrs_textSize,30); ta.recycle(); }}TypedArray要记得释放。
然后重写onMeasure,onDraw,这里用不到onLayout。绘制View,还需要画笔(Paint)和画布(Canvas),画布在onDraw中有封装,直接用就好了,我们自己创建一个Paint对象。因为要在指定区域内绘制文字,所以我们还需要创建Rect对象,在构造函数中实例化,不要在onDraw中实例化。
private Paint paint;private Rect r;
paint = new Paint();r = new Rect();下面我们先来设置画笔属性,绘制背景框:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制矩形区域 paint.setColor(bgColor); paint.setStrokeWidth(3); paint.setAntiAlias(true); canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint); }
效果如图:
我们发现这个区域是全屏的,我们不需要这么大,只需要按钮大小,此时就需要用到onMeasure了。根据模式设置默认大小。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if(widthMode == MeasureSpec.EXACTLY){ }else{ widthSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,300,getResources().getDisplayMetrics()); } if(heightMode == MeasureSpec.EXACTLY){ }else{ heightSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,200,getResources().getDisplayMetrics()); } setMeasuredDimension(widthSize,heightSize); }此时效果:
然后我们需要给画笔设置文字,设置字体,获取文字的宽高。
private String str = "4232";
//获取文字宽高,绘制文字paint.setTextSize(textSize);paint.setColor(textColor);paint.getTextBounds(str,0,str.length(),r);canvas.drawText(str,getWidth()/2-r.width()/2,getHeight()/2+r.height()/2,paint);效果如图:
下面需要实现点击变化文字,实现View的点击事件,我们这里取四位随机数,然后点击后设置给绘制的字符串。
//生成随机字符串 private String changeText(){ Random random = new Random(); String num = ""; for(int i = 0;i < 4;i++){ num = num + random.nextInt(10); } return num; }现在我们要的效果就实现了。
附上全部View的代码:
public class MyView extends View implements View.OnClickListener{ //背景色 private int bgColor; //文字色 private int textColor; //文字大小 private int textSize; private Paint paint; private Rect r; private String str = "4232"; public MyView(Context context) { this(context,null); } public MyView(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyViewAttrs,defStyleAttr,0); bgColor = ta.getColor(R.styleable.MyViewAttrs_bgColor, Color.BLACK); textColor = ta.getColor(R.styleable.MyViewAttrs_textColor,Color.WHITE); textSize = ta.getDimensionPixelSize(R.styleable.MyViewAttrs_textSize,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 30,getResources().getDisplayMetrics())); ta.recycle(); setOnClickListener(this); paint = new Paint(); r = new Rect(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if(widthMode == MeasureSpec.EXACTLY){ }else{ widthSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,200,getResources().getDisplayMetrics()); } if(heightMode == MeasureSpec.EXACTLY){ }else{ heightSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,100,getResources().getDisplayMetrics()); } setMeasuredDimension(widthSize,heightSize); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制矩形区域 paint.setColor(bgColor); paint.setStrokeWidth(3); paint.setAntiAlias(true); canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint); //获取文字宽高,绘制文字 paint.setTextSize(textSize); paint.setColor(textColor); paint.getTextBounds(str,0,str.length(),r); canvas.drawText(str,getWidth()/2-r.width()/2,getHeight()/2+r.height()/2,paint); } //生成随机字符串 private String changeText(){ Random random = new Random(); String num = ""; for(int i = 0;i < 4;i++){ num = num + random.nextInt(10); } return num; } @Override public void onClick(View view) { str = changeText(); invalidate(); }}
- android自定义View基础系列一(点击随机生成验证码效果)
- Android:自定义View(随机生成验证码)
- Android 自定义View之随机生成图片验证码
- Android 自定义View之随机生成图片验证码
- 自定义view(一)--随机验证码
- android 自定义view实现验证码效果(一)
- Android自定义View实现随机验证码
- Android 自定义view - 随机验证码
- android 自定义控件以及自定义view学习(随机验证码生成)
- android 自定义控件以及自定义view学习(随机验证码生成)
- android自定义View基础系列一
- Android从零开搞系列:自定义View(16)自定义验证码输入框效果
- android 自定义View生成验证码
- Android实现随机验证码——自定义View
- Android实现随机验证码——自定义View
- Android自定义View(一)(验证码)
- Android自定义View之点击效果
- 自定义View控件点击随机生成4位数
- 没报错但hibernate无法创建表
- 5.C++ 内联函数、参数可变函数、函数重载
- UIViewContentMode使用
- Laravel 5.3框架-多项目公用框架-架构设计方案
- db2统计每个表的行数
- android自定义View基础系列一(点击随机生成验证码效果)
- 文件操作工具类 FileUtils常用方法
- centos7(vm)下hadoop2.7.2 3节点集群(2副本)+flume1.4.0版本分布式 log收集在本地(x86)
- js跳转页面,新建一个标签页面方法
- Dm365 VPBE 后端模块讲解
- android IM即时通信之聊天界面UI框架
- Android 四大组件五大布局
- opencv cvNot色彩反相
- 阿里云服务器架设javaweb网站全攻略