canvas教程

自定义view之view显示流程(3)

字号+ 作者:H5之家 来源:H5之家 2017-04-18 17:04 我要评论( )

上面就是FrameLayout的测量过程,结合注释能看得很明白。首先FrameLayout会测量所有的子view,如果FrameLayout的大小是确定的,那么一轮测量就可以确定所有子view的大 H绻鸉rameLayout的大小不确定,比如设置为wr

上面就是FrameLayout的测量过程,结合注释能看得很明白。首先FrameLayout会测量所有的子view,如果FrameLayout的大小是确定的,那么一轮测量就可以确定所有子view的大小。如果FrameLayout的大小不确定,比如设置为wrap_content,那么此时那些宽或高参数为match_parent的子view是无法被确切测量大小的,因为此时parent的大小都还不知道呢,并且这些子view会存到mMatchParentChildren里。一轮测量下来,此时FrameLayout的宽和高分别都是测量过的子view的最大的宽和最大的高(最大的宽和最大的高不一定会出现在同一个子view上)。为防止出现极端情况,比如所有的子view宽高参数都是match_parent,那么此时测量出来的宽和高都是0(为什么是0后面会解释)。因此还需要对比一下最小的建议值以及前景的宽和高。

最后一轮是测量那些宽或高参数为match_parent的子view,此时FrameLayout的大小已经确定了,然后使用FrameLayout的SpecMode和第一轮刚测量出来的宽高重新构造子view的MeasureSpec,然后再重新测量。

至于父layout怎么测量子view的,其实从onMeasure的第二轮测量中就可以看到,首先父layout会依据自己的MeasureSpec和要测量的子view的LayoutParams.width、LayoutParams.height来生成子view的MeasureSpec,然后将这个MeasureSpec传给子view的measure方法,子view再根据自己的情况来测量自己大小。在父layout生成子view的MeasureSpec的过程中,主要是getChildMeasureSpec方法,浏览一下这个方法的源代码。

/** * Does the hard part of measureChildren: figuring out the MeasureSpec to * pass to a particular child. This method figures out the right MeasureSpec * for one dimension (height or width) of one child view. * * The goal is to combine information from our MeasureSpec with the * LayoutParams of the child to get the best possible results. For example, * if the this view knows its size (because its MeasureSpec has a mode of * EXACTLY), and the child has indicated in its LayoutParams that it wants * to be the same size as the parent, the parent should ask the child to * layout given an exact size. * * @param spec The requirements for this view * @param padding The padding of this view for the current dimension and * margins, if applicable * @param childDimension How big the child wants to be in the current * dimension * @return a MeasureSpec integer for the child */ public static int getChildMeasureSpec(int spec, int padding, int childDimension) { int specMode = MeasureSpec.getMode(spec); int specSize = MeasureSpec.getSize(spec); int size = Math.max(0, specSize - padding); int resultSize = 0; int resultMode = 0; switch (specMode) { // Parent has imposed an exact size on us case MeasureSpec.EXACTLY: if (childDimension >= 0) { resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size. So be it. resultSize = size; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break; // Parent has imposed a maximum size on us case MeasureSpec.AT_MOST: if (childDimension >= 0) { // Child wants a specific size... so be it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size, but our size is not fixed. // Constrain child to not be bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break; // Parent asked to see how big we want to be case MeasureSpec.UNSPECIFIED: if (childDimension >= 0) { // Child wants a specific size... let him have it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size... find out how big it should // be resultSize = 0; resultMode = MeasureSpec.UNSPECIFIED; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size.... find out how // big it should be resultSize = 0; resultMode = MeasureSpec.UNSPECIFIED; } break; } return MeasureSpec.makeMeasureSpec(resultSize, resultMode); }

方法并不难,我们可以很清晰地看到父layout是如何生产子view的MeasureSpec的,各项的注释也写得很清楚,总结起来如下表:

itdadao

这个很简单,可以看到父layout是如何根据自己的MeasureSpec和子view的LayoutParams来创建子view的MeasureSpec的。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Android开发基本常识及技巧

    Android开发基本常识及技巧

    2017-04-13 16:02

  • Android Canvas练习题(6)饼图(Pie Chart)百分比标注位置计算技巧

    Android Canvas练习题(6)饼图(Pie Chart)百分比标注位置计算技巧

    2017-04-12 11:00

  • Android Canvas clipPath 画图锯齿问题

    Android Canvas clipPath 画图锯齿问题

    2017-04-11 11:04

  • 实现Unity和Android进行交互

    实现Unity和Android进行交互

    2017-04-10 09:02

网友点评
h