Trying to replicate GridLayout column alignment with ConstraintLayout

Venator85 picture Venator85 · Mar 16, 2017 · Viewed 13.3k times · Source

I'm new to ConstraintLayout, and I'm trying to replicate the same grid behavior offered by GridLayout with ConstraintLayout.

Specifically, I want to design a two columns grid. The first column width should be as narrow as possible, while the second column should take all the remaining horizontal space. Of course, the second column should be just to the right of the first column, or rather, to the widest view on the first column.

I don't know how can I replicate this last requirement with ConstraintLayout. I don't want to use a Gridline between the two columns, because the first column should not have a fixed nor a percentage width, but rather be as wide as the widest of its view.

At https://gist.github.com/venator85/499dd82f47b3efbbed7a1e9e1ca1412d I prepared a layout example, and the corresponding preview, showing a GridLayout that implements what I want. The first two ConstraintLayout attempts in that layout show C1 and D1 be aligned to B1, and C2 and D2 be aligned to B2. When B2 is narrower than A2, A1 and C1 will overlap.

Any help?

Thanks

Answer

Cheticamp picture Cheticamp · Jun 1, 2017

Google has introduced the idea of "barriers" in the latest release of ConstraintLayout that helps to make an answer to this question 100% solvable in XML. See the ConstraintLayout 1.1.0 beta 1 release notes . Although, that note doesn't contain a lot of information on the new capabilities there was a talk at I/O 2017 that touched on the new stuff.

The new solution is to replicate the grid of GridLayout with barriers. There is a vertical barrier placed to the right of the left-hand TextViews and a barrier under the top three rows. The barriers shift depending upon how much text is present in each TextView but always maintain the position specified in app:constraint_referenced_ids. In essence, barriers act like floating guidelines. This solution is not relying upon any coding to support what is in the video.

Here is a video of the new layout that shows the desired positioning each TextView being maintained as the contents of another TextView changes. The video was made in the design tools of Android Studio 2.3.2.

And XML for the new layout using barriers:

<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/constrained"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.constraint.Barrier
        android:id="@+id/barrierVertical"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:barrierDirection="right"
        app:constraint_referenced_ids="L1, L2, L3, L4" />

    <TextView
        android:id="@+id/L1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="L1 *"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/R1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L1, R1" />

    <TextView
        android:id="@+id/L2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="L2 L2*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier1"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/R2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier1"
        tools:ignore="HardcodedText" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L2, R2" />

    <TextView
        android:id="@+id/L3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="L3 L3 L3*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier2"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/R3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3*"
        app:layout_constraintLeft_toRightOf="@id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier2"
        tools:ignore="HardcodedText" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L3, R3" />

    <TextView
        android:id="@+id/L4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="L4 L4 L4 L4 L4 L4*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier3"
        tools:ignore="HardcodedText,RtlHardcoded" />

    <TextView
        android:id="@+id/R4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier3"
        tools:ignore="HardcodedText" />

</android.support.constraint.ConstraintLayout>