UI绘制流程

2017-03-14  本文已影响20人  爱码士平头哥

在上一篇文章自定义控件中,其实已经比较全面的介绍了自定义控件的知识,在这里,我主要来做一次查漏补缺,以及分享一些阅读源码的一些心得。

首先,简单的来看看绘制流程经常用到的方法:

注意:为了方便阅读我故意把一些有参数的方法参数也去掉了。

View

measure()、onmeasure()

从上图可以看出,View的requestFitSystemWindows, requestLayout, invalidateChildInParent时候,都会调用measure方法。

而onMeasure方法一般是需要自己去定义高宽规则的时候重写它。

再者,measure的三种mode要分清楚:

MeasureSpec.UNSPECIFIED://未指定  (一般不用)

MeasureSpec.AT_MOST://至多  wrap_content

MeasureSpec.EXACTLY://精确   指定高度、宽度

layout()、onLayout()

1. 自定义一个view时,建议重写onLayout,以设定它的位置。

在外部调用时,调用layout(),触发设定位置。

2. 自定义一个viewGroup时,必须且只能重写onLayout。

需要在设定子view的位置:调用subview.layout(); 触发

draw()、ondraw()、dispatchdraw()

draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法, dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和getIntrinsicWidth(),

invalidate()、postInvalidate()

invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。 一个Android 程序默认情况下也只有一个进程,但一个进程下却可以有许多个线程。

requestLayout()

当一个View需要parent view重新调用他的onMeasure onLayout来对重新设置自己位置时,特别是当你修改了view的layout parameter,它的值还没能应用到view上,调用这个方法就可以了,但是要注意parent view的onLayout是怎么实现的。

上一篇下一篇

猜你喜欢

热点阅读