参考文章http://blog.csdn.net/lmj623565791/article/details/24252901
自定义View的基本步骤:
1.设置自定义view的属性。
2.在自定义view的构造方法中获取自定义的属性。
3.重写onMeasure().[非必须]。
4.重写onDraw()。
1.自定义属性
在res/values目录下建立attrs文件,定义属性和声明整个式样。
2. 在构造函数中获取自定义的属性
在布局文件中默认调用两个参数的构造函数,获取自定义属性需要通过三个参数的构造函数,因此,让所有构造函数都调用三个参数的构造函数。
在布局文件中,声明自定义view。自定义属性标签是"app: ",引入xmlns:app="http://schemas.android.com/apk/res-auto"
4.重写onDraw()方法
3.重写onMeasure()方法
情况1:直接调用父类onMeasure()方法,自定义view的宽高写wrap_content时。
当是自定义大小时,能正常显示。当设置为wrap_content或match_parent时候,系统测量的结果都是match_parent。因此,当为wrap_content的时候,我们要重写onMeasure()方法。
MeasureSpec是的SpecMode有3种类型:
1.EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
2.AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
3.UNSPECIFIED:表示子布局想要多大就多大,很少使用
重写onMeasure()之后,就恢复正常了。
给自定义view实现点击时候的,text内容实现类似验证码的变化
SP:
1. onDraw()是在初始化完成之后调用,postInvalidate()是重绘的,也就是调用postInvalidate()后系统会重新调用onDraw方法画一次。
2. Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
3. paint.getTextBounds 获取text宽度
Rect rect =new Rect();
paint.getTextBounds(str,0, str.length(), rect);
intw = rect.width();
inth = rect.height();
Log.d(TAG,"w="+w+" h="+h);