Android面试系列文章2018之Android部分View绘制机制篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClAndEllen/article/details/79365250

Android面试系列文章2018之Android部分View绘制机制篇

Android面试系列2018知识总结:
http://blog.csdn.net/ClAndEllen/article/details/79257663

1.View树的绘制流程

  measure(测量)–>layout(布局)–>draw(绘制)

2.Measure过程

这里写图片描述

a.ViewGroup.LayoutParams

b.MeasureSpec(测量规格)

  measure过程主要就是从顶层父View向子View递归调用view.measure方法(measure中又回调onMeasure方法)的过程。具体measure核心主要有如下几点:

MeasureSpec(View的内部类)测量规格为int型,值由高2位规格模式specMode和低30位具体尺寸specSize组成。其中specMode只有三种值:

  • MeasureSpec.EXACTLY //确定模式,父View希望子View的大小是确定的,由specSize决定;
  • MeasureSpec.AT_MOST //最多模式,父View希望子View的大小最多是specSize指定的值;
  • MeasureSpec.UNSPECIFIED //未指定模式,父View完全依据子View的设计值来决定;

View的measure方法是final的,不允许重载,View子类只能重载onMeasure来完成自己的测量逻辑。

最顶层DecorView测量时的MeasureSpec是由ViewRootImpl中getRootMeasureSpec方法确定的(LayoutParams宽高参数均为MATCH_PARENT,specMode是EXACTLY,specSize为物理屏幕大小)。

ViewGroup类提供了measureChild,measureChild和measureChildWithMargins方法,简化了父子View的尺寸计算。

只要是ViewGroup的子类就必须要求LayoutParams继承子MarginLayoutParams,否则无法使用layout_margin参数。

扫描二维码关注公众号,回复: 3286190 查看本文章

View的布局大小由父View和子View共同决定。

使用View的getMeasuredWidth()和getMeasuredHeight()方法来获取View测量的宽高,必须保证这两个方法在onMeasure流程之后被调用才能返回有效值。

3.Layout过程

  整个layout过程比较容易理解,从上面分析可以看出layout也是从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上。具体layout核心主要有以下几点:

  • View.layout方法可被重载,ViewGroup.layout为final的不可重载,ViewGroup.onLayout为abstract的,子类必须重载实现自己的位置逻辑。

  • measure操作完成后得到的是对每个View经测量过的measuredWidth和measuredHeight,layout操作完成之后得到的是对每个View进行位置分配后的mLeft、mTop、mRight、mBottom,这些值都是相对于父View来说的。

  • 凡是layout_XXX的布局属性基本都针对的是包含子View的ViewGroup的,当对一个没有父容器的View设置相关layout_XXX属性是没有任何意义的(前面《Android应用setContentView与LayoutInflater加载解析机制源码分析》也有提到过)。

  • 使用View的getWidth()和getHeight()方法来获取View测量的宽高,必须保证这两个方法在onLayout流程之后被调用才能返回有效值。

4.Draw过程

  绘制过程就是把View对象绘制到屏幕上,整个draw过程需要注意如下细节:

  • 如果该View是一个ViewGroup,则需要递归绘制其所包含的所有子View。

  • View默认不会绘制任何内容,真正的绘制都需要自己在子类中实现。

  • View的绘制是借助onDraw方法传入的Canvas类来进行的。

  • 区分View动画和ViewGroup布局动画,前者指的是View自身的动画,可以通过setAnimation添加,后者是专门针对ViewGroup显示内部子视图时设置的动画,可以在xml布局文件中对ViewGroup设置layoutAnimation属性(譬如对LinearLayout设置子View在显示时出现逐行、随机、下等显示等不同动画效果)。

  • 在获取画布剪切区(每个View的draw中传入的Canvas)时会自动处理掉padding,子View获取Canvas不用关注这些逻辑,只用关心如何绘制即可。

  • 默认情况下子View的ViewGroup.drawChild绘制顺序和子View被添加的顺序一致,但是你也可以重载ViewGroup.getChildDrawingOrder()方法提供不同顺序。

此篇博客借助了以下链接的内容,由于笔者只针对面试,所以你要想详细了解View的绘制机制,那么请你点击以下链接进行学习:
http://blog.csdn.net/yanbober/article/details/46128379/

猜你喜欢

转载自blog.csdn.net/ClAndEllen/article/details/79365250
今日推荐