View绘制过程及原理

作者: lucifer121 | 来源:发表于2016-11-16 18:04 被阅读116次

         View的绘制过程就是从ViewRoot的performTraversals方法开始的,它先后经过measurelayoutdraw三个过程才能最终将一个View绘制出来。分别对应onMeasure()、onLayout()和onDraw()这三个方法。下面分别谈一下这三个方法。

    measure

        measure是用来测量view的宽和高。在measure方法中又会调用onMeasure方法,在onMeasure方法中会对所有的子元素进行measure过程,这个时候measure流程就从父容器传递到子元素中了

    measure()方法接收两个参数,widthMeasureSpec和heightMeasureSpec,这两个值分别用于确定视图的宽度和高度的测量规格。MeasureSpec代表一个32的int值,高2位代表SpecMode测量模式,低30位代表SpecSize测量规格大小。SpecMode 分为三类

      1.EXACTLY(完全)

        父容器完全决定view的大小,子view的大小被忽略,被限定在给定的边界里。

      2.AT_MOST(至多)

        子view最多达到给定大小的值

      3.UNSPECIFIED(未指定)

        父容器不对view的大小做任何限制,子view可以得到任意想要的大小

      在setMeasuredDimension()方法调用之后,我们才能使用getMeasuredWidth()和getMeasuredHeight()来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是0。

    layout

      layout方法是在measure方法结束后进行,此时view的大小已经测量好了。layout的作用是ViewGroup用来确定子元素的位置,当ViewGroup的位置被确定后,它在onLayout中会遍历所有的子元素并调用Layout方法,在layout方法中onLayout方法又会被调用。这样一层一层的完成所有子View的布局过程。layout里面通过setFrame来确定View的四个顶点的位置,然后再layout中调用onLayout,这个方法用来确定子View的位置,起到一层层传递的作用。

    draw

      draw方法是在layout方法结束后进行,顾名思义,这里是绘制view的地方。draw主要分为6步。

      1.绘制view的背景图

      2.如果要视图显示渐变框,开始准备

      3.调用onDraw()函数,绘制视图本身。在view中进入onDraw()方法会发现是个空方法,因为每个子类视图的内容部分都是各不相同的,所以需要在子类中去重载,自己绘制

      4.绘制子视图,调用dispatchDraw()。如果视图中没有子视图,就不需要绘制了。因此你会发现View中的dispatchDraw()方法又是一个空方法,而ViewGroup的dispatchDraw()方法中就会有具体的绘制代码

      5.如果要视图显示渐变框,这里开始绘制

      6.绘制滚动条

     显然 第2和第5步基本是用不到的。重要的是第3步。

    相关文章

      网友评论

        本文标题:View绘制过程及原理

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