momvart
momvart

Reputation: 1999

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.

Upvotes: 1

Views: 2109

Answers (3)

momvart
momvart

Reputation: 1999

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>

Upvotes: 4

Shweta Chauhan
Shweta Chauhan

Reputation: 6981

Using chain style spread might be you got your expected layout.

enter image description here

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_25"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/entercode_default"
        android:text="25%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btn_50"
        app:layout_constraintHorizontal_chainStyle="spread"
        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:background="@drawable/entercode_default"
        android:text="50%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btn_75"
        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:background="@drawable/entercode_default"
        android:text="75%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btn_100"
        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:background="@drawable/entercode_default"
        android:text="100%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/btn_75"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 0

Tayyab Mazhar
Tayyab Mazhar

Reputation: 1712

So this is what i came up with:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/tv_25"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="16dp"
        android:text="25%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/tv_50"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/tv_50"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="16dp"
        android:text="50%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintLeft_toRightOf="@id/tv_25"
        app:layout_constraintRight_toLeftOf="@id/tv_75"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/tv_75"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="16dp"
        android:text="75%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintLeft_toRightOf="@id/tv_50"
        app:layout_constraintRight_toLeftOf="@id/tv_100"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/tv_100"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:text="100%"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintLeft_toRightOf="@id/tv_75"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Explanation: I've used app:layout_constraintHorizontal_chainStyle="spread".Using chain takes the margin into account while spreading the views evenly.

Upvotes: 0

Related Questions