View的工作原理浅谈(知识总结)

作者: lonamessi | 来源:发表于2018-03-05 16:05 被阅读31次

    这篇文章只是一个简单自定义知识总结,浅谈自定义View。
    在学习自定义View之前我们先了解一下几个概念。

    一 ViewRoot,DecorView

    ViewRoot是什么? ViewRoot对应于ViewRootImpl类,看到了很多人写的是viewtree的根节点,其实它跟View没有任何关系,也不是ViewTree的根节点,ViewTree的根节点往往是DecorView,DecorView的根是PhoneWindow,所以ViewRoot不是ViewTree的根节点,ViewRoot将DecorView attach到PhoneWindow上,连接WindowManager和DecorView的纽带。


    742015-20160507011816138-502436220 (1).png

    二 View的绘制流程概括

    View的绘制流程是从ViewRoot的performTraversals方法开始,然后调用onmeasure,onlayout,ondraw最终绘制出来view。(此处不做深入探讨,以后会分析)


    X)W_JJ7O57M%$E8F71_1NOA.png
    performTraversals的工作流程

    performTraversals会依次调用

    • performMeasure---->measure--->onMeasure---->从父容器传递到子View
    • performLayout ---->layout ---->onLayout--->从从父容器传递到子View
    • performDraw--->draw---->onDraw--->从父容器传递到子View

    三 Mearsure,Layout,Draw的工作流程

    Mearsure

    测量分为两种情况

    • view 的测量
    1. view的测量是通过measure的方法来测量的
    2. measure方法调用了onMeasure方法,传入参数MeasureSpec,其中 onMeasure方法对MeasureSpec进行处理
    3. onMeasure方法中调用了setMeasuredDimension()方法去设置View的具体宽高值
    4. getDefaultSize()此方法传入MeasureSpec,由此来确定宽高。
    • ViewGroup的测量
      1.先遍历去调用所有子元素的measure方法,各个子元素再递归去执行这个流程.
    1. ViewGroup结合自己的特性(比如竖直,水平等)给出自身的measure值。
      这里有一个重要的类需要解释那就是MeasureSpec
    MeasureSpec

    (选自开发艺术探索)
    MeasureSpec代表一个32位int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode是指测量模式,而specSize是指在某种测量模式下的规格大小。
    其中SpecMode有三个类

    • UNSPECIFIED

    父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。

    • EXACTLY

    父容器已经测量出View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值。它对应于LayoutParams中的match_parent(填充父元素,因为父元素的大小是固定的所以也相当于是具体数值)和具体的数值这两种模式。

    • AT_MOST

    父容器指定了一个可用大小即SpecSize,View大小不能大于这个值,(就是有最大限制)具体是什么值要看不同View的具体实现。它对应于LayoutParams中的Wrap_content

    Layout

    用来确定子元素的位置,当ViewGroup的位置被确定后,它在onLayout中会遍历所有的子元素并调用自身的layout方法,在layout方法中onLayout方法会被调用。layout方法确定View本身的位置,onLayout方法则会确定所有子元素的位置。

    这里有一个小问题需要解释一下就是:getMeasuredHeight(getMeasuredWidth),和getHeight(getWidth)的区别

    友情链接:Android开发之getMeasuredWidth和getWidth区别从源码分析

    1. getMeasuredWidth方法获得的值是setMeasuredDimension方法设置的值,它的值在measure方法运行后就会确定

    2. getWidth方法获得是layout方法中传递的四个参数中的mRight-mLeft,它的值是在layout方法运行后确定的

    3. 一般情况下在onLayout方法中使用getMeasuredWidth方法,而在除onLayout方法之外的地方用getWidth方法。

    4.在几乎所有的情况下都是相等的。

    draw

    这个过程就比较简单了,就是根据上面的数据进行绘制到屏幕上。

    相关文章

      网友评论

        本文标题:View的工作原理浅谈(知识总结)

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