本文为学习--启舰大神--自定义控件系列博客学习记录
- postInvalidate()、invadite()区别
postInvalidate()、invadite()都是重绘。
invadite() 必须在主线程中调用。
postInvalidate() 内部是由Handler的消息机制实现的,所以在任何线程中都可以调用,但实时性没有invadite() 强,所以一般为了保险起见,都是用 postInvalidate()来刷新界面。
- onDraw()、dispatchDraw() 区别
onDraw() 是绘制视图本身;dispatchDraw() 是绘制子视图。
无论是View还是ViewGroup对他们两个的调用顺序都是onDraw()->dispatchDraw()
在view中,onDraw() 和dispathDraw() 都会被调用,所以无论把绘图代码放在onDraw()或者dispatchDraw()中,都可以得到效果。由于dispatchDraw()的含义是绘制子控件,所以原则上来讲,在绘制View控件时,我们是重写onDraw() 方法。
结论是:在绘制View控件时,需要重写onDraw()方法,在绘制ViewGroup时,需要重写dispatchDraw()方法。
- super.dispatchDraw(canvas); 位置问题
@Override protected void dispatchDraw(Canvas canvas) { [..内容1..] super.dispatchDraw(canvas); [..内容2..] } 当我们重写dispatchDraw方法时,内部代码是写在内容1的位置还是内容2的位置呢?也就是super是否写在内容上面还是写在内容下面。首先我们需要知道super.dispatchDraw(canvas);的作用是什么。 super.dispatchDraw(canvas);的作用是绘制出该控件的所有子控件。子控件即在类内部new出来的控件。
两种效果,相信大家一看就明白了。
- canvas.save() 、canvas.savelayer() 、canvas.restore()
canvas.save():每次调用save() 函数,都会把当前的画布的状态进行保存,然后放入特定的栈中。
canvas.savelayout() :会创建一个全新透明的bitmap,大小与指定保存的区域一致,其后的绘图操作都会放在这个bitmap上进行,绘制结束后,会直接盖在上一层的bitmap上显示。在使用savelayer新建画布时,要选择适当的大小,不然很可能OOM。
canvas.restore():当调用restore() 函数时,就会把栈中最顶层的画布状态取出来,并按照这个状态恢复当前画布。
canvas.drawXXX系列函数来绘图时,都会产生一个全新的Canvas画布。
在Canvas与屏幕合成时,超出屏幕范围的图片不会显示出来。