@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int count = getChildCount(); int left = 0; int top = 0; int right = r - l; int bottom = b - t; if (needsSort) { if (count > 1) { // No need to sort one item. viewSorter.clear(); for (int i = 0; i < count; i++) { View child = getChildAt(i); TiCompositeLayout.LayoutParams params = (TiCompositeLayout.LayoutParams) child.getLayoutParams(); params.index = i; viewSorter.add(child); } detachAllViewsFromParent(); int i = 0; for (View child : viewSorter) { attachViewToParent(child, i++, child.getLayoutParams()); } } needsSort = false; } int[] horizontal = new int[2]; int[] vertical = new int[2]; int currentHeight = 0; for (int i = 0; i < count; i++) { View child = getChildAt(i); TiCompositeLayout.LayoutParams params = (TiCompositeLayout.LayoutParams) child.getLayoutParams(); if (child.getVisibility() != View.GONE) { // Dimension is required from Measure. Positioning is determined here. int childMeasuredWidth = child.getMeasuredWidth(); int childMeasuredHeight = child.getMeasuredHeight(); computePosition( params.optionLeft, params.optionRight, childMeasuredWidth, left, right, horizontal); if (this.vertical) { computeVerticalLayoutPosition( currentHeight, params.optionTop, params.optionBottom, childMeasuredHeight, top, bottom, vertical); } else { computePosition( params.optionTop, params.optionBottom, childMeasuredHeight, top, bottom, vertical); } if (DBG) { Log.d( TAG, child.getClass().getName() + " {" + horizontal[0] + "," + vertical[0] + "," + horizontal[1] + "," + vertical[1] + "}"); } int newWidth = horizontal[1] - horizontal[0]; int newHeight = vertical[1] - vertical[0]; if (newWidth != childMeasuredWidth || newHeight != childMeasuredHeight) { int newWidthSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY); int newHeightSpec = MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY); child.measure(newWidthSpec, newHeightSpec); } child.layout(horizontal[0], vertical[0], horizontal[1], vertical[1]); currentHeight += newHeight; if (params.optionTop != NOT_SET) { currentHeight += params.optionTop; } } } }