In creating a custom ViewGroup that expected all children to lay out to the entire available space, I encountered unexpected behavior when passing in RelativeLayout instances as children. Specifically, ALIGN_PARENT_BOTTOM worked, as did it if I also passed ALIGN_PARENT_RIGHT, but the latter without the former did not work (the child was not laid out whatever), not did other rules like CENTER_IN_PARENT. The basic idea was pretty straightforward:

As you can see, we’re never even referencing the child’s LayoutParams – all children should fill all available space (imagine a 2-axis ScrollView). In testing, generally the behavior will be as expected (e.g., background color will fill appropriately, borders will be drawn where expected, etc). However, ViewGroups with complex layouts may show strange behavior (see my notes about RelativeLayout rules, above).

The cause is measureChildren, which calls measureChild, which queries the child directly for it’s LayoutParams and passes them to getChildMeasureSpec for determining measure and layout intention. Thus, even the ViewGroup above, which normally has no need of child LayoutParams, can incorrectly compute where a child should be positioned.

The fix is to call child.measure directly, passing in the MeasureSpec values solely determined by the ViewGroup. onLayout would not need to be changed, but the modified onMeasure would look like this: