1. Invalidate() 指定重新绘制部分区域
2. requestLayout() 是当view大小改变的时候,调用
3. Canvas 画什么 比如画圆,方形等
4. Paint 怎么画 颜色,线条粗细等,创建paint很耗资源,所以最好在初始化的时候创建好,不要在onDraw方法里面创建
5. 继承onSizeChanged(),决定view改变时候的绘制方式;这里其实是对绘制新的图形做一些处理,onSizeChanged()传给你四个值,可供你利用,然后你根据这四个值来决定他们改变后,你的view里面各个元素怎么绘制。注意,padding 是算在view内的,而margin则不算在view内。所以决定元素绘制位置的时候,可以不考虑margin但是必须考虑padding
6. onMeasure()方法,传入两个int型参数,widthMeasureSpec 、 heightMeasureSpect,这两个int值可以通过MeasureSpect类得到另外两个值(得到方法是这个int值&一个掩码或者该掩码的补码),一个是measure的类型mode, 另外就是这个measure值:
Measure Mode包括三种,Exactly 大致等于设置了layout_width = 60dp 这样, AT_MOST大致等于match_parent这样;UNSPECIFIED大致等于wrap_content这样;
measuredSpec这个值就是parent view给子view的限制了,最大是多大。
onMeasure方法获得这些信息后,就可以来决定自己的view到底要绘制多大,
通常onMeasure方法里面会调用一下resolveSizeAndState()或者resolveSize ()这两个方法,大致是传入你要的size和parent给的size,并且做出一个协调结果,省了你自己去判断parent的MeasureSpec Mode了。另外还加上一个掩码,目前我还不太清楚这个掩码是干什么用的
总之,调用完onMeasure()方法后,一定要调用setMeasureDimension()来决定最终的宽和高。
7. 在量完这个view的宽,高(onMeasure方法),view内部各个部件该绘制到哪个位置之后,就可以实现onDraw()方法来实际绘制了。
参考:绘制view过程见官方:
http://developer.android.com/training/custom-views/index.html
有关onMeasure的说明:
http://stackoverflow.com/questions/12266899/onmeasure-custom-view-explanation
有关resolveSizeAndState 见源码:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/view/View.java#View.0MEASURED_STATE_MASK
Note:
invalidate() 会导致view 调用onDraw(),如果传入四个参数,就重新绘制那个方形内的东西
requestLayout()是一个非常费时的调用,尽量保持View Hierarchy不要太深,如果有复杂的布局的话,可以考虑
写一个自定义的ViewGroup, 这里面来安排子布局,而不需要系统来自己算了。
使用硬件加速,注意,硬件加速在图形变换上很在行,比如移动,转动;但是在绘制基本图形上不太在行。解决方案是
可以把要每次重新绘制的东西想办法让他通过移动,变换来完成,比如放到一个view里面。具体方法见官网。