OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.widget; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.util.AttributeSet; |
| 9 import android.view.View; |
| 10 import android.view.ViewGroup; |
| 11 |
| 12 import org.chromium.base.ApiCompatibilityUtils; |
| 13 |
| 14 /** |
| 15 * ViewGroup that places child views in lines from start to end, wraps items to |
| 16 * next line if content too long to hold in one line. |
| 17 */ |
| 18 public class FlowLayout extends ViewGroup { |
| 19 private static final int SPACING_DEFAULT_DP = 3; |
| 20 |
| 21 private int mHorizontalSpacing; |
| 22 private int mVerticalSpacing; |
| 23 |
| 24 public FlowLayout(Context context, AttributeSet attrs) { |
| 25 super(context, attrs); |
| 26 int spacingDefaultPx = Math.round( |
| 27 getResources().getDisplayMetrics().density * SPACING_DEFAULT_DP)
; |
| 28 mHorizontalSpacing = spacingDefaultPx; |
| 29 mVerticalSpacing = spacingDefaultPx; |
| 30 } |
| 31 |
| 32 @Override |
| 33 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 34 int availableWidth = MeasureSpec.getSize(widthMeasureSpec) |
| 35 - ApiCompatibilityUtils.getPaddingEnd(this); |
| 36 int widthMode = MeasureSpec.getMode(widthMeasureSpec); |
| 37 |
| 38 boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED; |
| 39 |
| 40 int width = 0; |
| 41 int height = getPaddingTop(); |
| 42 |
| 43 int currentWidth = ApiCompatibilityUtils.getPaddingStart(this); |
| 44 int currentHeight = 0; |
| 45 |
| 46 boolean newLine = false; |
| 47 int spacing = 0; |
| 48 |
| 49 final int count = getChildCount(); |
| 50 for (int i = 0; i < count; i++) { |
| 51 View child = getChildAt(i); |
| 52 measureChild(child, widthMeasureSpec, heightMeasureSpec); |
| 53 |
| 54 LayoutParams lp = (LayoutParams) child.getLayoutParams(); |
| 55 spacing = mHorizontalSpacing; |
| 56 |
| 57 if (growHeight && currentWidth + child.getMeasuredWidth() > availabl
eWidth) { |
| 58 height += currentHeight + mVerticalSpacing; |
| 59 currentHeight = 0; |
| 60 width = Math.max(width, currentWidth - spacing); |
| 61 currentWidth = ApiCompatibilityUtils.getPaddingStart(this); |
| 62 newLine = true; |
| 63 } else { |
| 64 newLine = false; |
| 65 } |
| 66 |
| 67 lp.start = currentWidth; |
| 68 lp.top = height; |
| 69 |
| 70 currentWidth += child.getMeasuredWidth() + spacing; |
| 71 currentHeight = Math.max(currentHeight, child.getMeasuredHeight()); |
| 72 |
| 73 } |
| 74 |
| 75 if (!newLine) { |
| 76 height += currentHeight; |
| 77 width = Math.max(width, currentWidth - spacing); |
| 78 } |
| 79 |
| 80 width += ApiCompatibilityUtils.getPaddingEnd(this); |
| 81 height += getPaddingBottom(); |
| 82 |
| 83 setMeasuredDimension(resolveSize(width, widthMeasureSpec), |
| 84 resolveSize(height, heightMeasureSpec)); |
| 85 } |
| 86 |
| 87 @Override |
| 88 protected void onLayout(boolean changed, int l, int t, int r, int b) { |
| 89 // Entire width of layout group |
| 90 int width = r - l; |
| 91 boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this); |
| 92 for (int i = 0; i < getChildCount(); i++) { |
| 93 View child = getChildAt(i); |
| 94 LayoutParams lp = (LayoutParams) child.getLayoutParams(); |
| 95 int left = isRtl ? width - lp.start - child.getMeasuredWidth() : lp.
start; |
| 96 child.layout(left, lp.top, left + child.getMeasuredWidth(), |
| 97 lp.top + child.getMeasuredHeight()); |
| 98 } |
| 99 } |
| 100 |
| 101 @Override |
| 102 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { |
| 103 return p instanceof LayoutParams; |
| 104 } |
| 105 |
| 106 @Override |
| 107 protected LayoutParams generateDefaultLayoutParams() { |
| 108 return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CON
TENT); |
| 109 } |
| 110 |
| 111 @Override |
| 112 public LayoutParams generateLayoutParams(AttributeSet attrs) { |
| 113 return new LayoutParams(getContext(), attrs); |
| 114 } |
| 115 |
| 116 @Override |
| 117 protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { |
| 118 return new LayoutParams(p.width, p.height); |
| 119 } |
| 120 |
| 121 /** |
| 122 * LayoutParams for FlowLayout. |
| 123 */ |
| 124 public static class LayoutParams extends ViewGroup.LayoutParams { |
| 125 // distance from start of view group to start of the view. |
| 126 public int start; |
| 127 // vertical coordinate of the view |
| 128 public int top; |
| 129 |
| 130 public LayoutParams(Context context, AttributeSet attrs) { |
| 131 super(context, attrs); |
| 132 } |
| 133 |
| 134 public LayoutParams(int w, int h) { |
| 135 super(w, h); |
| 136 } |
| 137 } |
| 138 } |
OLD | NEW |