美文网首页Android开发安卓资源收集Android技术知识
LinearLayout中child View被测量次数分析

LinearLayout中child View被测量次数分析

作者: 辣条超人 | 来源:发表于2016-09-05 11:33 被阅读710次

    本文会分析【垂直布局】的LinearLayout中child 被测量次数。

    图1.1 垂直布局的LinearLayout 的onMeasure()流程图

    图1.1为 垂直布局的LinearLayout 中的onMearsure()方法的大体流程(由于是垂直布局,onMearsure()方法实际上回调用measureVertical()方法)。在measureVertical()方法中总共有3个地方会进行测量。分别需要满足【A为假】,【B为真】,【C为真】三个条件。

    1 Use a layout_height of 0dp instead of for bettererformance
    图1.2Android Studio 中的LinearLayout优化提示

    当你在LinearLayout中嵌套一个使用了weight的View时,Android Studio会提示你:为了更好的性能,将layout_height设置为0dp。这样做确实可以提高性能,但仅仅是可以而不是100%。在LinearLayout中如果发现满足一定条件(图1.1中的【优化条件A为真】)就可以让【这些weight>0的child】跳过第一次测量,只进行图1.1中深红色部分的测量,从而减少了一次测量,提升了性能。但是跳过第一次测量的条件不仅仅需要layout_height == 0,weight > 0,还需要LinearLayout的parent在高上给的mode != MeasureSpec.EXACTLY(也就是 MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY)。
    当你使用LinearLayout时,parent给的mode有3种情况。所以就算你遵循了Android Studio给的优化建议,优化也不一定生效。

    2 "尽量避免在LinearLayout中使用weight ,因为这样的话child会被测量2次"

    经常在网上看到这句说的非常不靠谱的话,使用了weight的child也有可能只被测量1次,被测量一次的情况有如下3种:

    1.chlid满足前面1中Android Studio给的优化提示。
    2.child没有跳过第一次测量,但是计算出来的(条件B中的delta为0)值为0。
    3.满足getVisibility() == View.GONE的child
    

    第二种情况中的delta会被根据权重分配给使用了大于0的weight的child。其实,不管child有没有使用weight,只要为GONE,就完全不会被测量。

    3总结

    在LinearLayout中,如果为GONE的child和没有weight的child在onMeasure方法中永远只会被测量一次。对于children应该分开来看,因为有可能在一次onMeasure()的执行过程中,其中一部分child被测量的1次,另外的child被测量了2次。当在说“某个LinearLayout由于使用了weight而导致了性能的问题”时,其实是在说“由于使用了weight,这个LinearLayout中的【一部分(有可能是区青年布)】child被测量了2次”,千万不要认为只要使用了weight,【所有的】child都会被测量2次。如果需要判断某个child被测量的次数,只需要对照图1.1中的流程图就行了(这里的流程图针对垂直布局来画的,水平布局可能略有不同)

    相关文章

      网友评论

        本文标题:LinearLayout中child View被测量次数分析

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