我很有意思获得与css float: left
风格相同的效果。我现在正在使用RelativeLayout
和android:layout_toRightOf
,但是当它们不合适时需要观看到下一行。如何在Android布局中实现这一点?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="300dp" />
<Button
android:id="@+id/b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/a"
android:width="300dp" />
<Button
android:id="@+id/c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/b"
android:width="300dp" />
</RelativeLayout>
我需要像example
这样的内容在更宽的屏幕上,我需要在一行中获得例如 3个按钮,但在较小的屏幕上,一行中有2个按钮,第二行中有三个按钮。如下图所示。
较小的设备
更广泛的设备
答案 0 :(得分:2)
对于单行,请使用水平方向的LinearLayout
而不是RelativeLayout。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- add your views here -->
</LinearLayout>
对于多行,您希望自动将元素“流”到新行。您可以查看android flow-layout project或根据this custom implementation
尝试实施自己的{{3}}/** Custom view which extends {@link RelativeLayout}
* and which places its children horizontally,
* flowing over to a new line whenever it runs out of width.*/
public class HorizontalFlowLayout
extends RelativeLayout
{
/** Constructor to use when creating View from code.*/
public HorizontalFlowLayout(Context context)
{
super(context);
}
/** Constructor that is called when inflating View from XML.*/
public HorizontalFlowLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
/** Perform inflation from XML and apply a class-specific base style.*/
public HorizontalFlowLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// need to call super.onMeasure(...) otherwise get some funny behaviour
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
// increment the x position as we progress through a line
int xpos = getPaddingLeft();
// increment the y position as we progress through the lines
int ypos = getPaddingTop();
// the height of the current line
int line_height = 0;
// go through children
// to work out the height required for this view
// call to measure size of children not needed I think?!
// getting child's measured height/width seems to work okay without it
//measureChildren(widthMeasureSpec, heightMeasureSpec);
View child;
MarginLayoutParams childMarginLayoutParams;
int childWidth, childHeight, childMarginLeft, childMarginRight, childMarginTop, childMarginBottom;
for (int i = 0; i < getChildCount(); i++)
{
child = getChildAt(i);
if (child.getVisibility() != GONE)
{
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
if (child.getLayoutParams() != null
&& child.getLayoutParams() instanceof MarginLayoutParams)
{
childMarginLayoutParams = (MarginLayoutParams)child.getLayoutParams();
childMarginLeft = childMarginLayoutParams.leftMargin;
childMarginRight = childMarginLayoutParams.rightMargin;
childMarginTop = childMarginLayoutParams.topMargin;
childMarginBottom = childMarginLayoutParams.bottomMargin;
}
else
{
childMarginLeft = 0;
childMarginRight = 0;
childMarginTop = 0;
childMarginBottom = 0;
}
if (xpos + childMarginLeft + childWidth + childMarginRight + getPaddingRight() > width)
{
// this child will need to go on a new line
xpos = getPaddingLeft();
ypos += line_height;
line_height = childMarginTop + childHeight + childMarginBottom;
}
else
// enough space for this child on the current line
line_height = Math.max(
line_height,
childMarginTop + childHeight + childMarginBottom);
xpos += childMarginLeft + childWidth + childMarginRight;
}
}
ypos += line_height + getPaddingBottom();
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED)
// set height as measured since there's no height restrictions
height = ypos;
else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST
&& ypos < height)
// set height as measured since it's less than the maximum allowed
height = ypos;
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
// increment the x position as we progress through a line
int xpos = getPaddingLeft();
// increment the y position as we progress through the lines
int ypos = getPaddingTop();
// the height of the current line
int line_height = 0;
View child;
MarginLayoutParams childMarginLayoutParams;
int childWidth, childHeight, childMarginLeft, childMarginRight, childMarginTop, childMarginBottom;
for (int i = 0; i < getChildCount(); i++)
{
child = getChildAt(i);
if (child.getVisibility() != GONE)
{
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
if (child.getLayoutParams() != null
&& child.getLayoutParams() instanceof MarginLayoutParams)
{
childMarginLayoutParams = (MarginLayoutParams)child.getLayoutParams();
childMarginLeft = childMarginLayoutParams.leftMargin;
childMarginRight = childMarginLayoutParams.rightMargin;
childMarginTop = childMarginLayoutParams.topMargin;
childMarginBottom = childMarginLayoutParams.bottomMargin;
}
else
{
childMarginLeft = 0;
childMarginRight = 0;
childMarginTop = 0;
childMarginBottom = 0;
}
if (xpos + childMarginLeft + childWidth + childMarginRight + getPaddingRight() > r - l)
{
// this child will need to go on a new line
xpos = getPaddingLeft();
ypos += line_height;
line_height = childHeight + childMarginTop + childMarginBottom;
}
else
// enough space for this child on the current line
line_height = Math.max(
line_height,
childMarginTop + childHeight + childMarginBottom);
child.layout(
xpos + childMarginLeft,
ypos + childMarginTop,
xpos + childMarginLeft + childWidth,
ypos + childMarginTop + childHeight);
xpos += childMarginLeft + childWidth + childMarginRight;
}
}
}
}
答案 1 :(得分:0)
使用此代码可将任意屏幕尺寸设备的三个按钮分成1行。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="3" >
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"/>
</LinearLayout>