Android 强制查看组';s的子项如果超过设备宽度,则移动到下一行
我想有一个视图组,它可能有一些视图,这些视图水平放置在一起。我的代码的问题是,一切都很好,但当子项计数越来越大时,所有子项水平放置在一起并超过设备宽度。如果它们超过设备宽度,我需要强制它们移动到下一行 这是我的代码:Android 强制查看组';s的子项如果超过设备宽度,则移动到下一行,android,viewgroup,device-width,Android,Viewgroup,Device Width,我想有一个视图组,它可能有一些视图,这些视图水平放置在一起。我的代码的问题是,一切都很好,但当子项计数越来越大时,所有子项水平放置在一起并超过设备宽度。如果它们超过设备宽度,我需要强制它们移动到下一行 这是我的代码: <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="92dp" android:layo
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="92dp"
android:layout_marginTop="?attr/actionBarSize"
android:background="@color/divider"
android:padding="6dp">
<LinearLayout
android:id="@+id/linear_layout_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"></LinearLayout>
<ImageButton
android:id="@+id/image_button_add_item"
android:layout_width="78dp"
android:layout_height="match_parent"
android:background="@color/secondary_text"
android:contentDescription="@string/content_description_add_new_file"
android:src="@drawable/ic_plus"/>
</LinearLayout>
注意:线性布局容器
视图组包含所有视图,所有视图都是线性布局视图组的子视图。为了将它们移动到下一行,您必须进行一些测量,但如果您想要一个简单的解决方案:
- 您只需将它们
匹配即可
- 或者给它们一个固定的宽度大小,并使用权重(您确实需要使用为
MATCH\u PARRENT
和水平布局设置的线性布局来包装它们)
- 或者你可以玩2015年8月推出的新款
默认情况下,线性布局就是这样工作的。出于您的目的,您需要一个FlowLayout
罗曼盖伊的流动布局
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class FlowLayout extends ViewGroup {
private int mHorizontalSpacing;
private int mVerticalSpacing;
private Paint mPaint;
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();
}
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(0xffff0000);
mPaint.setStrokeWidth(2.0f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec)
- getPaddingRight();
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;
int width = 0;
int height = getPaddingTop();
int currentWidth = getPaddingLeft();
int currentHeight = 0;
boolean breakLine = false;
boolean newLine = false;
int spacing = 0;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
spacing = mHorizontalSpacing;
if (lp.horizontalSpacing >= 0) {
spacing = lp.horizontalSpacing;
}
if (growHeight
&& (breakLine || currentWidth + child.getMeasuredWidth() > widthSize)) {
height += currentHeight + mVerticalSpacing;
currentHeight = 0;
width = Math.max(width, currentWidth - spacing);
currentWidth = getPaddingLeft();
newLine = true;
} else {
newLine = false;
}
lp.x = currentWidth;
lp.y = height;
currentWidth += child.getMeasuredWidth() + spacing;
currentHeight = Math.max(currentHeight, child.getMeasuredHeight());
breakLine = lp.breakLine;
}
if (!newLine) {
height += currentHeight;
width = Math.max(width, currentWidth - spacing);
}
width += getPaddingRight();
height += getPaddingBottom();
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 drawChild(Canvas canvas, View child, long drawingTime) {
boolean more = super.drawChild(canvas, child, drawingTime);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.horizontalSpacing > 0) {
float x = child.getRight();
float y = child.getTop() + child.getHeight() / 2.0f;
canvas.drawLine(x, y - 4.0f, x, y + 4.0f, mPaint);
canvas.drawLine(x, y, x + lp.horizontalSpacing, y, mPaint);
canvas.drawLine(x + lp.horizontalSpacing, y - 4.0f, x
+ lp.horizontalSpacing, y + 4.0f, mPaint);
}
if (lp.breakLine) {
float x = child.getRight();
float y = child.getTop() + child.getHeight() / 2.0f;
canvas.drawLine(x, y, x, y + 6.0f, mPaint);
canvas.drawLine(x, y + 6.0f, x + 6.0f, y + 6.0f, mPaint);
}
return more;
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends ViewGroup.LayoutParams {
int x;
int y;
public int horizontalSpacing;
public boolean breakLine;
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.FlowLayout_LayoutParams);
try {
horizontalSpacing = a
.getDimensionPixelSize(
R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing,
-1);
breakLine = a.getBoolean(
R.styleable.FlowLayout_LayoutParams_layout_breakLine,
false);
} finally {
a.recycle();
}
}
public LayoutParams(int w, int h) {
super(w, h);
}
}
}
导入android.content.Context;
导入android.content.res.TypedArray;
导入android.graphics.Canvas;
导入android.graphics.Paint;
导入android.util.AttributeSet;
导入android.view.view;
导入android.view.ViewGroup;
公共类FlowLayout扩展了ViewGroup{
私人国际水平间距;
私有整数垂直间距;
私人油漆;
公共流布局(上下文、属性集属性){
超级(上下文,attrs);
TypedArray a=上下文。获取样式属性(属性,
R.styleable.FlowLayout);
试一试{
mHorizontalSpacing=a.getDimensionPixelSize(
R.styleable.FlowLayout_水平间距,0);
mVerticalSpacing=a.getDimensionPixelSize(
R.styleable.FlowLayout_垂直间距,0);
}最后{
a、 回收();
}
mPaint=新油漆();
mPaint.setAntiAlias(true);
mPaint.setColor(0xffff0000);
mPaint.设定行程宽度(2.0f);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
int widthSize=MeasureSpec.getSize(widthMeasureSpec)
-getPaddingRight();
int widthMode=MeasureSpec.getMode(widthmasurespec);
布尔增长高度=宽度模式!=MeasureSpec.UNSPECIFIED;
整数宽度=0;
int height=getPaddingTop();
int currentWidth=getPaddingLeft();
int currentHeight=0;
布尔特征线=假;
布尔换行=假;
整数间距=0;
最终整数计数=getChildCount();
for(int i=0;i=0){
间距=lp.水平间距;
}
如果(生长高度)
&&(特征线| | currentWidth+child.getMeasuredWidth()>widthSize)){
高度+=当前高度+垂直间距;
当前高度=0;
宽度=数学最大值(宽度,当前宽度-间距);
currentWidth=getPaddingLeft();
换行符=真;
}否则{
换行符=假;
}
lp.x=电流宽度;
lp.y=高度;
currentWidth+=child.getMeasuredWidth()+间距;
currentHeight=Math.max(currentHeight,child.getMeasuredHeight());
特征线=lp.特征线;
}
如果(!换行){
高度+=当前高度;
宽度=数学最大值(宽度,当前宽度-间距);
}
宽度+=getPaddingRight();
高度+=getPaddingBottom();
设置测量尺寸(resolveSize(宽度、宽度测量等级),
分辨率尺寸(高度、高度测量值);
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
最终整数计数=getChildCount();
for(int i=0;i0){
float x=child.getRight();
float y=child.getTop()+child.getHeight()/2.0f;
帆布抽绳(x,y-4.0f,x,y+4.0f,mPaint);
帆布.抽绳(x,y,x+lp.horizontalSpacin