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

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

一 ViewRoot,DecorView

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


View的工作原理浅谈(知识总结)_第1张图片
742015-20160507011816138-502436220 (1).png

二 View的绘制流程概括

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


View的工作原理浅谈(知识总结)_第2张图片
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的工作原理浅谈(知识总结))