androidandroid-constraintlayoutconstraint-layout-chains

ConstraintLayout spread views inside with same width


I want to have a horizontal alignment of four buttons with these conditions:

Is it possible to achieve this using ConstraintLayout?

To demonstrate what I exactly want, take a look at current state of my layout (which is ok): enter image description here

The buttons currently are set to have a width of 25 percent of the parent and there's a static margin between them (implemented using a LinearLayout). What is the problem? It's possible in small screens that the margin cause the last button to be truncated (like the image below), or in large screens the buttons be so large.

enter image description here

So I want the spread behavior of ConstraintLayout besides width of the last button be wrap_content and width of other buttons be set equal to the last button.


Solution

  • Thanks to @cheticamp and his answer provided here, the best way of achieving the desired behavior would be writing a simple ConstraintHelper which sets width of all the children to the maximum among them.

    class MaxWidthConstraint @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
    ) : ConstraintHelper(context, attrs, defStyleAttr) {
        override fun updatePostMeasure(container: ConstraintLayout) {
            val maxWidth =
                referencedIds.asSequence().map { container.getViewById(it) }
                    .map { container.getViewWidget(it) }
                    .map { it.width }
                    .max() ?: 0
            referencedIds.asSequence().map { container.getViewById(it) }
                .map { container.getViewWidget(it) }
                .forEach { it.width = maxWidth }
        }
    }
    

    So the layout code would be:

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="HardcodedText">
    
        <Button
            android:id="@+id/btn_25"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="25%"
            android:textAlignment="center"
            app:layout_constraintEnd_toStartOf="@id/btn_50"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_50"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="50%"
            app:layout_constraintEnd_toStartOf="@id/btn_75"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toEndOf="@id/btn_25"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_75"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="75%"
            app:layout_constraintEnd_toStartOf="@id/btn_100"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toEndOf="@id/btn_50"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_100"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="100%"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toEndOf="@id/btn_75"
            app:layout_constraintTop_toTopOf="parent" />
    
        <com.myapplication.widgets.MaxWidthConstraint
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:constraint_referenced_ids="btn_25,btn_50,btn_75,btn_100"
            tools:ignore="MissingConstraints" />
    </androidx.constraintlayout.widget.ConstraintLayout>