/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package android.windowanimationjank; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * Custom layout that place all elements in flows with and automatically wraps them. */ public class FlowLayout extends ViewGroup { private int mLineHeight; public FlowLayout(Context context) { super(context); } public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() -getPaddingRight(); int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom(); final int count = getChildCount(); int x = getPaddingLeft(); int y = getPaddingTop(); int lineHeight = 0; int childHeightMeasureSpec; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); } else { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec); final int childWidth = child.getMeasuredWidth(); lineHeight = Math.max(lineHeight, child.getMeasuredHeight()); if (x + childWidth > width) { x = getPaddingLeft(); y += lineHeight; } x += childWidth; } } mLineHeight = lineHeight; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) { height = y + lineHeight; } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { if (y + lineHeight < height) { height = y + lineHeight; } } setMeasuredDimension(width, height); } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { if (p instanceof LayoutParams) { return true; } return false; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); final int width = r - l; int x = getPaddingLeft(); int y = getPaddingTop(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); if (x + childWidth > width) { x = getPaddingLeft(); y += mLineHeight; } child.layout(x, y, x + childWidth, y + childHeight); x += childWidth; } } } }