View工作流程之Measure

view的几个工作流程

  • measure 负责测量控件以及子控件的尺寸信息
  • layout 负责布局
  • draw 负责绘制

measure流程的分类

我们知道,view可以分为两种类型,view以及viewgroup。

view的典型例子就是我们常见的TextView, ImageView等,
viewgroup指拥有子元素的布局,常见的就是我们熟悉的各种layout。

根据类型的不同,其measure流程也有不同。

View的measure流程

首先会调用view内部一个名叫measure的final方法,这个方法由于是final的,我们不能复写,但是其中调用了一个名叫onMeasure的方法,这是我们可以复写的。

先来看一个调用流程图

onMeasure流程图

在onMeasure的源码中,我们可以看到,只有一个函数调用,那就是:

setMeasureDimension方法会根据spaceMode和spacSize来确定大小,这两个参数都可以从MeasureSpec中解析获取。

可以看到内部又调用了一个getSuggestedMiniWidth()方法,在这个方法中,会根据是否有背景来确定View的最小尺寸,如果没有,那么最小宽/高就跟默认值一样,如果有,那么就跟背景的最小值相同。

如何获取默认值呢?这根据View的类型有所不同,有的View有默认值,有的View没有,正如书上所讲的一个例子,ShapeDrawable没有默认值,而BitmapDrawable有默认值。

ViewGroup的measure流程

在ViewGroup中,并没有重写onMeasure方法,但是有一个measureChildren方法,在该方法中会对每一个子元素进行measure。

在不同的ViewGroup子类中由于布局方式不同,所以onMeasure的实现也有所不同,所以ViewGroup并未对onMeasure方法做统一的实现。

measure过程和activity的生命周期并不是同步的

由于measure的过程和activity的生命周期并不是同步的,所以我们用一般的方法是不能在view还没有measure完毕之前在activity中获取其高度等信息的,如何解决呢,这里作者给出了四种方法。

1.复写onWindowFocusChanged方法,在该方法中,测量过程已经完成
2.使用view.post(runnable)方法
3.ViewTreeObserver的回调onGlobalLayout()方法
4.在View.measure中测量,但是此方法受到layoutparam的限制,在match_parent时无法使用

u3coding
A software developer

Leave a Comment

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.