【发布时间】:2012-12-26 21:38:57
【问题描述】:
我正在创建一个具有流式布局的应用程序。我从网上找到的FlowLayout 实现(我不记得确切来自哪里)。现在,当我的布局宽度大于其子项宽度的总和时,我需要填充空白空间,给每个适当的宽度。我试图给他们MATCH_PARENT 作为宽度,但它没有用,每个元素都是从“新行”创建的。
请帮我解决我的问题。提前致谢。
这是我使用的 FlowLayout 类实现:
public class FlowLayout extends ViewGroup {
public static final String TAG = FlowLayout.class.getSimpleName();
private int mHorizontalSpacing = 10;
private int mVerticalSpacing = 10;
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
try {
mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 0);
mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 0);
} finally {
a.recycle();
}
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int width = 0;
int height = getPaddingTop();
int currentWidth = getPaddingLeft();
int currentHeight = 0;
boolean breakLine = false;
final int count = getChildCount();
Log.d(TAG, "child count = " + count);
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
measureChild(child, widthMeasureSpec, heightMeasureSpec);
Log.d(TAG, "child " + i + " mw=" + child.getMeasuredWidth() + " mh=" + child.getMeasuredHeight());
if (breakLine || currentWidth + child.getMeasuredWidth() > widthSize) {
height += currentHeight + mVerticalSpacing;
currentHeight = 0;
if (currentWidth > width) width = currentWidth;
currentWidth = getPaddingLeft();
}
int spacing = mHorizontalSpacing;
if (lp.spacing != Integer.MAX_VALUE) {
spacing = lp.spacing;
}
lp.x = currentWidth;
lp.y = height;
Log.d(TAG, "child " + i + " x=" + lp.x + " y=" + lp.y);
currentWidth += child.getMeasuredWidth() + spacing;
int childHeight = child.getMeasuredHeight();
if (childHeight > currentHeight) currentHeight = childHeight;
breakLine = lp.breakLine;
}
// after last row (patched by yuku)
{
height += currentHeight;
if (currentWidth > width) width = currentWidth;
}
width += getPaddingRight();
height += getPaddingBottom();
Log.d(TAG, "onMeasure w=" + width + " h=" + height + " widthMeasureSpec=" + Integer.toHexString(widthMeasureSpec) + " heightMeasureSpec=" + Integer.toHexString(heightMeasureSpec));
// don't resolve height (patched by yuku)
setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec));
}
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight());
}
}
@Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override public LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override public LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends ViewGroup.LayoutParams {
public boolean breakLine;
public int spacing = Integer.MAX_VALUE;
private int x;
private int y;
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout_LayoutParams);
try {
spacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_spacing, Integer.MAX_VALUE);
breakLine = a.getBoolean(R.styleable.FlowLayout_LayoutParams_layout_breakLine, false);
} finally {
a.recycle();
}
}
}
}
我想实现这个效果:
而不是这个:
【问题讨论】:
-
实际上没有人可以回答有关自定义未知 3rd 方控件的问题。但如果是内置的 LinearLayout,我建议在组中的任何元素上将宽度设置为 0,将权重设置为 1。
-
嗯,我认为这是 Romain Guy 在视频中提出的自定义布局。 Karlen:您至少应该发布 FlowLayout 的确切代码。此外,您可能想尝试更详细地解释您想要发生的事情与实际发生的事情。
-
vortexx,感谢您的帮助,我会尽快尝试。 @dmon 我已经添加了你想要的信息。
标签: java android flowlayout fill-parent