自定义View之draw()与onDraw()方法

draw()方法

下面是View的draw()方法的注释部分:

/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
*      1. Draw the background
*      2. If necessary, save the canvas' layers to prepare for fading
*      3. Draw view's content
*      4. Draw children
*      5. If necessary, draw the fading edges and restore layers
*      6. Draw decorations (scrollbars for instance)
*/

第二步和第五步很少用到。总结一下的话,draw()方法做了这些事情:
(1)绘制背景。由private方法drawBackground()完成。如果未设定背景Drawable对象,则会直接返回。
(2)绘制内容。由onDraw()方法完成。
(3)绘制子视图。由dispatchView()完成。View的dispatchView()是空方法,ViewGroup的dispatchView()有具体实现,主要是调用子视图的draw()方法。
(4)绘制装饰。主要是foreground与滚动条。
因此,只要最高层的根布局调用了它的draw()方法,低层的所有view的draw()方法最终都会被调用。因此,大部分情况下draw()方法是不需要手动调用的,我们只需要覆盖onDraw()方法,将自己的内容绘制出来即可。

onDraw()方法

//View中的onDraw()方法
protected void onDraw(Canvas canvas) {
}

毫无疑问的,View的onDraw()方法是个空方法。基本上所有的自定义view都需要实现这个方法,否则无法显示任何内容。编程人员需要做的,就是利用Canvas类提供的各种方法,将内容绘制到正确的位置上。

invalidate()、postInvalidate()以及postInvalidateDelayed()

如果view的内容变化了,需要对其进行重绘。通过调用invalidate(),postInvalidate(),postInvalidateDelayed()这三个方法,最终都会进入onDraw()方法中。下面看看这三个方法的区别:

invalidate()

立即进行重绘。这个方法只能在UI线程中调用。

postInvalidate()

立即进行重绘。这个方法可以在非UI线程中调用。

postInvalidateDelayed(long delayMilliseconds)

延迟重绘。这个方法接受一个毫秒值,重绘会在经过了这么一段时间后进行。这个方法可以在非UI线程中调用。
补充一点:这三个方法都有一个重载版本,接受(int l, int t, int r, int b)这么一组参数。这组参数确定了一块“脏区域”,重绘只会在这块区域上进行。如果不提供的话,会默认重绘整块区域。

小技巧

如果想要实现每隔若干秒自动重绘一次要怎么做呢?很简单,在onDraw()中调用postInvalidateDelayed(delayMilliseconds)即可。

发布了42 篇原创文章 · 获赞 26 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览