美文网首页
Android View绘制简述

Android View绘制简述

作者: 静水红阳 | 来源:发表于2020-07-27 16:01 被阅读0次

    概述

    当启动一个应用时,会启动一个主Activity,Android系统会根据Activity的布局对它进行绘制。绘制会从根视图ViewRoot开始,从上到下遍历整个视图树,每个View控制负责绘制自己,而ViewGroup还需负责通知自己的子View进行绘制操作。
    视图View的绘制操作过程整体上可以分为三个操作部分:测量(Measure),布局(Layout),绘制(Draw)。

    MeasureSpec

    MeasureSpec是View类中的一个静态内部类,用来说明应该怎么测量这个View,包括有测量模式和测量模式下的尺寸大小SpecSize。
    MeasureSpec表示的是一个32位的整数值,他的高两位表示测量模式,低位表示测量的规格大小。

    测量模式包括三种:

    1. UpSecified(不指定测量模式):父视图没有限制子视图大小。
    2. Exactly(精准测量模式):当该视图的layout_width或者layout_height指定为具体数值或者match_parent时或具体值时生效,表示父视图已经决定了子视图的精确大小。
    3. At_Most(最大值模式):当前视图的宽高制定为wrap_content时生效,此时子视图的尺寸不可超过俯视图的最大尺寸。

    Measure

    Measure用来计算View的实际大小,页面的测量从preformMeasure方法开始。

    具体操作是分发给ViewGroup的,由ViewGroup在它的measureChild方法中传递给自View,ViewGroup通过便利自己所有子View,并逐个调用子View的measure方法实现测量操作。

    View的measure方法,最终的测量是通过回调onMeasure方法实现的,逐个由各个View的子类进行实现,可以通过重写这个方法实现自定义View。

    public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
        ...
        onMeasure(widthMeasureSpec, heightMeasureSpec);
        ....
      }
      
      // 如果需要自定义测量,子类需重写这个方法
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
        getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
      }
      
      // 如果 View 没有重写onMeasure 方法,默认会直接调用 getDefaultSize
       public static int getDefaultSize(int size, int measureSpec) {
         int result = size;
         int specMode = MeasureSpec.getMode(measureSpec);
         int specSize = MeasureSpec.getSize(measureSpec);
    
         switch (specMode) {
           case MeasureSpec.UNSPECIFIED:
              result = size;
              break;
           case MeasureSpec.AT_MOST:
           case MeasureSpec.EXACTLY:
              result = specSize;
              break;
          }
          return result;
       }
    

    Layout

    Layout过程用来确定View在父容器的布局位置,他是父容器获取子View的位置参数后,调用子View的layout方法并将位置参数传入实现的。

    View的layout方法是调用了onLayout方法,onLayout方法中是空方法,由View中的ViewGroup子类进行实现。

    自定义ViewGroup方法需要重写onLayout方法。

    public void layout(int l, int t, int r, int b) {
        onLayout(changed, l, t, r, b);
      }
    
      // 空方法,子类如果是 ViewGroup 类型,则重写这个方法,实现 ViewGroup 中所有 View 控件布局
      protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      }
    

    Draw

    Draw操作是将View控件进行绘制出来,绘制的流程从performDraw方法开始,最终调用到了每个View的draw方法进行绘制每个具体的View。

    绘制基本上可以分为六个步骤:

    1. 对View的背景进行绘制(drawBackground方法)
    2. 保存当前的图层信息(可跳过)
    3. 绘制View的内容(调用onDraw方法,View类是空实现,不同View中有不同内容)
    4. 对View的子View进行绘制(如果有子View)(调用dispatchDraw方法,View勒种为空,ViewGroup中重写)
    5. 绘制VIew的褪色的边缘,类似于阴影效果(可跳过)
    6. 绘制View的装饰(如滚动条等)

    相关文章

      网友评论

          本文标题:Android View绘制简述

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