Chain with a barrier in ConstraintLayout
Asked Answered
E

2

42

I want to achieve the layout below using a ConstraintLayout with no nesting.

enter image description here

The layout requires a barrier since it's not guaranteed which textview will be taller. It also requires a chain since everything needs to be centered. The issue is that I can't find a way to make chain work with barriers.

Here's what I have so far which will layout correctly but will not center:

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/topLeftText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        tools:text="Test test test test test test test test test test"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/topRightText"/>

    <TextView
        android:id="@+id/topRightText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginEnd="16dp"
        tools:text="Test test test test test test test test test test test test test test test test test test test test"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toEndOf="@+id/topLeftText"
        app:layout_constraintEnd_toEndOf="parent"/>

    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="topLeftText,topRightText"
        app:barrierDirection="bottom"/>

    <TextView
        android:id="@+id/bottomText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        tools:text="Test test test test test test test test test test test test test test test test test test test test"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier"/>

</android.support.constraint.ConstraintLayout>

If anyone knows how to achieve this, that would be much appreciated!

Etty answered 16/4, 2019 at 0:46 Comment(6)
Have you tried to constrain top of top left text view to top of top right text view. Then constrain top right and bottom text views to barrierCotter
Did you solve your problem, if yes how? I am currently facing a similar problem, and the only solution that i can think of otherwise, is using a nested layout. Which kinda contradicts the use of a ConstraintLayout, keeping the hierarchy flat.Cyrstalcyrus
have you found a workaround?Farcy
Is the problem you are facing that you cannot centre everything vertically? If this is the case maybe you can try using a horizontal guideline instead of a barrier?Bender
@Cyrstalcyrus I used a nested layout. Since this question still has no answers I think it's probably this is impossible to achieve without changes to ConstraintLayout.Etty
It just blows me away that there's no answer from google devs for this query till date.Preterit
C
1

I know it's old but i think to do that without nesting, you have to change top component to something like this.

android:layout_height="wrap_content" android:layout_gravity="center"

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
Cathedral answered 17/8, 2020 at 21:40 Comment(2)
The question is about centering TextViews inside ConstraintLayout. Your answer is about centering the ConstraintLayout inside it's parent. That is nesting, because you have to add such parent.Colley
@Colley There's no nesting in this answer. It's showing that the root/parent (ConstraintLayout in this case) can be wrapped and centered as a whole. There's no extra ViewGroup defined. Although the solution doesn't answer whether barrier chaining can be done it does show that the content can be centered.Peggie
B
0

Maybe you can use a guideline instead of a barrier. Let me know if this works for you:

Since you are not using androidx, make sure to replace androidx.constraintlayout.widget with android.support.constraint

<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">

    <TextView
        android:id="@+id/topLeftText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        app:layout_constraintBottom_toTopOf="@id/guideline"
        app:layout_constraintEnd_toStartOf="@+id/topRightText"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="Test test test test test test test test test test" />

    <TextView
        android:id="@+id/topRightText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        app:layout_constraintBottom_toTopOf="@id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/topLeftText"
        tools:text="Test test test test test test test test test test test test test test test test test test test test" />


    <TextView
        android:id="@+id/bottomText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/guideline"
        tools:text="Test test test test test test test test test test test test test test test test test test test test" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is how it will look like

enter image description here

Blackman answered 23/5, 2023 at 13:0 Comment(2)
This solution does not center the content as a unit. Imagine a situation where the text views at the top are a lot shorter than the text view at the bottom or vise versa.Etty
Oh, now I understand what you mean. Nesting the 2 upper views is an alternative, but I know that it doesn't answer your question.Blackman

© 2022 - 2024 — McMap. All rights reserved.