• android 中view的绘制过程


    view的绘制过程中分别会执行:onMeasure(会多次)计算view的大小,OnLayout(),确定控件的大小和位置 onDraw()绘制view

      当Activity获得焦点时,它将被要求绘制自己的布局,Android framework将会处理绘制过程,Activity只需提供它的布局的根节点。

      绘制过程从布局的根节点开始,从根节点开始测量和绘制整个layout tree。

      每一个ViewGroup负责要求它的每一个孩子被绘制,每一个View负责绘制自己。

      因为整个树是按顺序遍历的,所以父节点会先被绘制,而兄弟节点会按照它们在树中出现的顺序被绘制。

      

      绘制是一个两遍(two pass)的过程:一个measure pass和一个layout pass。

      测量过程(measuring pass)是在measure(int, int)中实现的,是从树的顶端由上到下进行的。

      在这个递归过程中,每一个View会把自己的dimension specifications传递下去。

      在measure pass的最后,每一个View都存储好了自己的measurements,即测量结果。

      第二个是布局过程(layout pass),它发生在layout(int, int, int, int)中,仍然是从上到下进行(top-down)。

      在这一遍中,每一个parent都会负责用测量过程中得到的尺寸,把自己的所有孩子放在正确的地方。

    尺寸的父子关系处理

      当一个View对象的measure() 方法返回时,它的 getMeasuredWidth()getMeasuredHeight()值应该被设置好了,并且它的所有子孙的值也应该一起被设置好了。

      一个View对象的measured width 和measured height的值必须考虑到它的父容器给它的限制。

      这样就保证了在measure pass的最后,所有的parent都接受了它的所有孩子的measurements结果。

      注意:一个parent可能会不止一次地对它的孩子调用measure()方法。

      比如,第一遍的时候,一个parent可能测量它的每一个孩子,并没有指定尺寸,parent只是为了发现它们想要多大;

      如果第一遍之后得知,所有孩子的无限制的尺寸总和太大或者太小,parent会再次对它的孩子调用measure()方法,这时候parent会设定规则,介入这个过程,使用实际的值。

      (即,让孩子自由发展不成,于是家长介入)。

    布局属性说明

      LayoutParams是View用来告诉它的父容器它想要怎样被放置的参数。

      最基本的LayoutParams基类仅仅描述了View想要多大,即指明了尺寸属性。

      即View在XML布局时通常需要指明的宽度和高度属性。

      每一个维度都可以指定成下列三种值之一:

      1.FILL_PARENT (API Level 8之后重命名为MATCH_PARENT),表示View想要尽量和它的parent一样大(减去边距)。

      2.WRAP_CONTENT,表示View想要刚好大到可以包含它的内容(包括边距)。

      3.具体的数值

      ViewGroup的不同子类(不同的布局类)有相应的LayoutParams子类,其中会包含更多的布局相关属性。

    onMeasure方法

      onMeasure方法是测量view和它的内容,决定measured width和measured height的,这个方法由measure(int, int)方法唤起,子类可以覆写onMeasure来提供更加准确和有效的测量。

      有一个约定:在覆写onMeasure方法的时候,必须调用setMeasuredDimension(int,int)来存储这个View经过测量得到的measured width and height。

      如果没有这么做,将会由measure(int, int)方法抛出一个IllegalStateException

      onMeasure方法的声明如下:

    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

      其中两个输入参数:

      widthMeasureSpec

      heightMeasureSpec

      分别是parent提出的水平和垂直的空间要求

      这两个要求是按照View.MeasureSpec类来进行编码的。

      参见View.MeasureSpec这个类的说明:这个类包装了从parent传递下来的布局要求,传递给这个child。

      每一个MeasureSpec代表了对宽度或者高度的一个要求。

      每一个MeasureSpec有一个尺寸(size)和一个模式(mode)构成。

      MeasureSpecs这个类提供了把一个<size, mode>的元组包装进一个int型的方法,从而减少对象分配。当然也提供了逆向的解析方法,从int值中解出size和mode。

      有三种模式:

      UNSPECIFIED

      这说明parent没有对child强加任何限制,child可以是它想要的任何尺寸。

      EXACTLY

      Parent为child决定了一个绝对尺寸,child将会被赋予这些边界限制,不管child自己想要多大。

      AT_MOST

      Child可以是自己任意的大小,但是有个绝对尺寸的上限。

      覆写onMeasure方法的时候,子类有责任确保measured height and width至少为这个View的最小height和width。

      (getSuggestedMinimumHeight() andgetSuggestedMinimumWidth())。

    onLayout

      这个方法是在layout pass中被调用的,用于确定View的摆放位置和大小。方法声明:

    protected void onLayout (boolean changed, int left, int top, int right, int bottom)

      其中的上下左右参数都是相对于parent的。

      如果View含有child,那么onLayout中需要对每一个child进行布局。

  • 相关阅读:
    Unity的DrawCall
    社交化分享SDK for Unity
    【收藏】75个很有用的开源移动工具
    日积月累--exception记录
    AndroidStudio 编译异常java.lang.OutOfMemoryError: GC overhead limit exceeded
    聊一聊 Android 6.0 的运行时权限
    一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!
    Git查看、删除、重命名远程分支和tag
    移动数据统计平台分析
    手把手教你AndroidStudio多渠道打包
  • 原文地址:https://www.cnblogs.com/jiayonghua/p/3709704.html
Copyright © 2020-2023  润新知