是否有为Android的LinearLayout设置的属性,使其能够正确包装子控件?
含义 - 我的孩子数量多变,并希望水平布置,如:
Example: Control1, Control2, Control3, ...
我这样设置:
ll.setOrientation(LinearLayout.HORIZONTAL); foreach (Child c in children) ll.addView(c);
但是,如果我有大量的孩子,最后一个会被切断,而不是去下一行.
知道如何解决这个问题吗?
Ran*_*ku' 55
这应该是你想要的:
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
*
* @author RAW
*/
public class FlowLayout extends ViewGroup {
private int line_height;
public static class LayoutParams extends ViewGroup.LayoutParams {
public final int horizontal_spacing;
public final int vertical_spacing;
/**
* @param horizontal_spacing Pixels between items, horizontally
* @param vertical_spacing Pixels between items, vertically
*/
public LayoutParams(int horizontal_spacing, int vertical_spacing) {
super(0, 0);
this.horizontal_spacing = horizontal_spacing;
this.vertical_spacing = vertical_spacing;
}
}
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);
final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
final int count = getChildCount();
int line_height = 0;
int xpos = getPaddingLeft();
int ypos = getPaddingTop();
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) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec);
final int childw = child.getMeasuredWidth();
line_height = Math.max(line_height, child.getMeasuredHeight() + lp.vertical_spacing);
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
xpos += childw + lp.horizontal_spacing;
}
}
this.line_height = line_height;
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
height = ypos + line_height;
} else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
if (ypos + line_height < height) {
height = ypos + line_height;
}
}
setMeasuredDimension(width, height);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(1, 1); // default of 1px spacing
}
@Override
protected android.view.ViewGroup.LayoutParams generateLayoutParams(
android.view.ViewGroup.LayoutParams p) {
return new LayoutParams(1, 1, p);
}
@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 xpos = getPaddingLeft();
int ypos = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final int childw = child.getMeasuredWidth();
final int childh = child.getMeasuredHeight();
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
child.layout(xpos, ypos, xpos + childw, ypos + childh);
xpos += childw + lp.horizontal_spacing;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
和XML文件
/* you must write your package name and class name */
<org.android.FlowLayout
android:id="@+id/flow_layout"
android:layout_marginLeft="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)
mys*_*obo 46
截至2016年5月,Google已经创建了自己的FlexBoxLayout
解决方案.
你可以在这里找到GitHub回购:https://github.com/google/flexbox-layout
nik*_*3ro 42
对于任何需要这种行为的人:
private void populateLinks(LinearLayout ll, ArrayList<Sample> collection, String header) {
Display display = getWindowManager().getDefaultDisplay();
int maxWidth = display.getWidth() - 10;
if (collection.size() > 0) {
LinearLayout llAlso = new LinearLayout(this);
llAlso.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
llAlso.setOrientation(LinearLayout.HORIZONTAL);
TextView txtSample = new TextView(this);
txtSample.setText(header);
llAlso.addView(txtSample);
txtSample.measure(0, 0);
int widthSoFar = txtSample.getMeasuredWidth();
for (Sample samItem : collection) {
TextView txtSamItem = new TextView(this, null,
android.R.attr.textColorLink);
txtSamItem.setText(samItem.Sample);
txtSamItem.setPadding(10, 0, 0, 0);
txtSamItem.setTag(samItem);
txtSamItem.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextView self = (TextView) v;
Sample ds = (Sample) self.getTag();
Intent myIntent = new Intent();
myIntent.putExtra("link_info", ds.Sample);
setResult("link_clicked", myIntent);
finish();
}
});
txtSamItem.measure(0, 0);
widthSoFar += txtSamItem.getMeasuredWidth();
if (widthSoFar >= maxWidth) {
ll.addView(llAlso);
llAlso = new LinearLayout(this);
llAlso.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
llAlso.setOrientation(LinearLayout.HORIZONTAL);
llAlso.addView(txtSamItem);
widthSoFar = txtSamItem.getMeasuredWidth();
} else {
llAlso.addView(txtSamItem);
}
}
ll.addView(llAlso);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
老问题,但万一有人在这里结束,两个库正是这样做的:
https://github.com/blazsolar/FlowLayout
https://github.com/ApmeM/android-flowlayout
过去,许多自定义解决方案和库都尝试过并确实解决了这个问题。
\n从现在开始Constraint Layout 2.0
我们可以使用Flow
\n\nFlow 是一种新的虚拟布局,用于构建链,当空间不足时,可以包裹到下一行,甚至屏幕的另一部分。当您\xe2\x80\x99在链中布置多个项目但您\xe2\x80\x99不太确定容器在运行时有多大时,这非常有用。您可以使用它来根据应用程序中的动态尺寸构建布局,例如旋转时的屏幕宽度。
\n
xml 如下所示:
\n<androidx.constraintlayout.helper.widget.Flow\n android:layout_width="0dp"\n android:layout_height="wrap_content"\n app:layout_constraintStart_toStartOf="parent"\n app:layout_constraintEnd_toEndOf="parent"\n app:layout_constraintTop_toTopOf="parent"\n app:flow_wrapMode="chain"\n app:constraint_referenced_ids="card1, card2, card3"\n />\n
Run Code Online (Sandbox Code Playgroud)\n注意app:constraint_referenced_ids
和app:flow_wrapMode
属性。
我们使用第一个视图传递视图,然后选择如何用第二个视图包装它们。
\napp:flow_wrapMode
接受 3 种不同的选项:
没有任何:create a single chain, overflowing if the content doesn\xe2\x80\x99t fit
链:on overflow, create add another chain for the overflow elements
对齐:similar to chain, but align rows into columns
有关更多详细信息,请查看Android 开发者帖子
\n和官方文档
\n 归档时间: |
|
查看次数: |
55970 次 |
最近记录: |