Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match all children width to widest child width in ConstraintLayout with width = wrap content

ConstraintLayout is powerful but tricky sometimes.

I want to implement a layout with the ConstraintLayout which can be easily achieved with the LinearLayout.

  • The Blue area is parent constraintLayout. The red part is LinearLayout. I want to convert this LinearLayout to ConstraintLayout by maintaining the following conditions

    1. All children (Buttons)'s width should match the widest child.
    2. The widest child is not fixed. It will be changed at runtime.
    3. The red box should remain to maintain wrap_content.

I have tried with doing with barrier, guidelines and other properties of constraint layout without success.

Here is the code with LinearLayout:

<android.support.constraint.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"
android:background="#476dce"
android:padding="16dp">

  <LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:background="#f5aaaa">


    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:text="Small" />

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:text="Bigggggeer" />


    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:text="Even Bigggggggggeer" />

  </LinearLayout>
</android.support.constraint.ConstraintLayout>
like image 416
HBB20 Avatar asked Aug 17 '18 19:08

HBB20


People also ask

What is ConstraintLayout?

A ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way. Note: ConstraintLayout is available as a support library that you can use on Android systems starting with API level 9 (Gingerbread). As such, we are planning on enriching its API and capabilities over time.

Can we use LinearLayout in ConstraintLayout?

Most of what can be achieved in LinearLayout and RelativeLayout can be done in ConstraintLayout. However, learning the basics of LinearLayout and RelativeLayout is important before trying to understand how to use it with ConstraintLayout.

How do you make a relative layout responsive?

Relative layout: image centered, minWidth set, texts have set toRightOf/toLeftOf. Relative layout: image has set toRightOf/toLeftOf. Constraint layout: "constraint arrows" go from image to text. Constraint layout: "constraint arrows" go from text to image.


1 Answers

The current 1.1 stable release allows a tricky solution based on Barriers and separate backgrounds.

enter image description here

    <android.support.constraint.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">

    <View
        android:id="@+id/background"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#f5aaaa"
        app:layout_constraintBottom_toBottomOf="@+id/button3_txt"
        app:layout_constraintLeft_toLeftOf="@+id/left_barrier"
        app:layout_constraintRight_toRightOf="@+id/right_barrier"
        app:layout_constraintTop_toTopOf="@+id/button1_txt" />

    <TextView
        android:id="@+id/button1_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="8dp"
        android:padding="16dp"
        android:text="small"
        app:layout_constraintBottom_toTopOf="@+id/button2_txt"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />

    <TextView
        android:id="@+id/button2_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="8dp"
        android:padding="16dp"
        android:text="Bigggggeer"
        app:layout_constraintBottom_toTopOf="@+id/button3_txt"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button1_txt" />

    <TextView
        android:id="@+id/button3_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="8dp"
        android:padding="16dp"
        android:text="Even Bigggggggggeer"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button2_txt" />

    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/button1_txt"
        app:layout_constraintLeft_toLeftOf="@+id/left_barrier"
        app:layout_constraintRight_toRightOf="@+id/right_barrier"
        app:layout_constraintTop_toTopOf="@+id/button1_txt" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/button2_txt"
        app:layout_constraintLeft_toLeftOf="@+id/left_barrier"
        app:layout_constraintRight_toRightOf="@+id/right_barrier"
        app:layout_constraintTop_toTopOf="@+id/button2_txt" />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/button3_txt"
        app:layout_constraintLeft_toLeftOf="@+id/left_barrier"
        app:layout_constraintRight_toRightOf="@+id/right_barrier"
        app:layout_constraintTop_toTopOf="@+id/button3_txt" />

    <android.support.constraint.Barrier
        android:id="@+id/right_barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="button1_txt, button2_txt, button3_txt" />

    <android.support.constraint.Barrier
        android:id="@+id/left_barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="start"
        app:constraint_referenced_ids="button1_txt, button2_txt, button3_txt" />

</android.support.constraint.ConstraintLayout>

We can separate texts from buttons, and set two barriers at each end to track the biggest text between the three TextViews.
So now, Buttons act only as a background and as click zones, and, they are set to match constraint between the two barriers.
You might want to be careful with elevation related to texts as Buttons have elevation by default. Of course, if you are not into Buttons' animated elevation, change them to views.
Finally, ConstraintLayout has the chains feature to mimic LinearLayout's behavior in a more flexible way.

Hope this helps!

like image 145
Rami Jemli Avatar answered Oct 10 '22 19:10

Rami Jemli