[英]How do I make children the same size in a Flow ConstraintLayout?
I have a bunch of tiles that I want to distribute horizontally across the screen.我有一堆要在屏幕上水平分布的图块。 They'll be too wide show up on a single row for most devices, so I'd like to use a ConstraintLayout with a Flow helper.
对于大多数设备来说,它们在一行中显示的太宽了,所以我想将 ConstraintLayout 与 Flow 助手一起使用。 I can get that to work.
我可以让它工作。
But I'd like to make sure each tile is the same width.但我想确保每个瓷砖的宽度相同。 Ideally each tile would be as wide as the required width of the widest tile.
理想情况下,每个瓷砖的宽度应与最宽瓷砖的所需宽度一样宽。 What's the right way to make sure that each element in my Flow gets the same width?
确保 Flow 中的每个元素都具有相同宽度的正确方法是什么?
(I tried creating a chain and using layout_constraintHorizontal_weight
but that just squeezes every tile into the same row and prevents the Flow from flowing.) (我尝试创建一个链并使用
layout_constraintHorizontal_weight
但这只是将每个图块挤入同一行并阻止 Flow 流动。)
I ended up adding a ViewTreeObserver that creates a ConstraintSet that sets the size of the children before layout occurs.我最终添加了一个ViewTreeObserver ,它创建了一个ConstraintSet ,它在布局发生之前设置了孩子的大小。 It isn't pretty, but it does roughly what I want:
它不漂亮,但它大致符合我的要求:
final ConstraintLayout statContainer = findViewById(R.id.stat_container);
statContainer.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
try {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(statContainer);
// Determine a minimum width
int width = 0;
for (int i = 0; i < statContainer.getChildCount(); i++) {
View child = statContainer.getChildAt(i);
if (child instanceof Flow) {
continue;
}
int candidateWidth = child.getMeasuredWidth();
width = Math.max(width, candidateWidth);
}
// Don't allow any child to get too big
int max = statContainer.getWidth() / 3;
width = Math.min(width, max);
// Set that width
for (int i = 0; i < statContainer.getChildCount(); i++) {
View child = statContainer.getChildAt(i);
if (child instanceof Flow) {
continue;
}
constraintSet.constrainWidth(child.getId(), width);
}
constraintSet.applyTo(statContainer);
statContainer.invalidate();
} finally {
statContainer.getViewTreeObserver().removeOnPreDrawListener(this);
}
return false;
}
});
You can achieve the same width for the children just using Flow
like this:您可以像这样使用
Flow
为孩子们实现相同的宽度:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/view1"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#333" />
<View
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#333" />
<View
android:id="@+id/view3"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#333" />
<View
android:id="@+id/view4"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#333" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:constraint_referenced_ids="view1,view2,view3,view4"
app:flow_horizontalGap="8dp"
app:flow_maxElementsWrap="2"
app:flow_verticalGap="8dp"
app:flow_wrapMode="chain"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Preview:预览:
Note: One downside in this solution is, if you have an odd number of elements, then the last element will fill the full width.注意:此解决方案的一个缺点是,如果您有奇数个元素,则最后一个元素将填满整个宽度。 You can programatically set the last element width at runtime.
您可以在运行时以编程方式设置最后一个元素的宽度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.