简体   繁体   English

如何在 Flow ConstraintLayout 中使孩子的大小相同?

[英]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.

相关问题 我如何以编程方式使约束布局包装我的textview - How do i make the constraintlayout wrap my textview programmatically 如何在屏幕外 position 的 ConstraintLayout 子项(以便稍后在屏幕上翻译它们)? - How do I position children of ConstraintLayout offscreen (so that I can translate them onscreen later)? 如何将 CoordinatorLayout 的直接子组件约束到 ConstraintLayout 内的组件? - How do I constrain components that are a direct children of CoordinatorLayout to components inside a ConstraintLayout? ConstraintLayout的孩子的边距不显示? - Margins on children of ConstraintLayout do not display? 如何使 ImageView 与图像的像素大小相同 - How do I make the ImageView the same size as the image in pixels 如何使6个按钮对齐且大小相同? - How do I make 6 buttons aligned and same size? 如何在 ConstraintLayout 的 Flow 助手中获取所有子视图/引用视图 - How to get all children/referenced views inside a ConstraintLayout's Flow helper 以编程方式更改ConstraintLayout子项的边距和大小 - Changing ConstraintLayout children's margin and size programmatically 如何在 ConstraintLayout 内重叠组件? - How do I overlap components inside a ConstraintLayout? 如何在ConstraintLayout中设置视图可见性? - How do I set view visiibility in a ConstraintLayout?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM