美文网首页
UI绘制流程

UI绘制流程

作者: 爱码士平头哥 | 来源:发表于2017-03-14 15:56 被阅读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是怎么实现的。

    相关文章

      网友评论

          本文标题:UI绘制流程

          本文链接:https://www.haomeiwen.com/subject/pvnwgttx.html