Constraint Layout with two chained TextViews doesn't render properly

Viewed 319

I'm trying to create an layout which renders two TextViews packed together as in picture #1. Now, when first (red) TextView has more text than the allowed space it expands itself to fit it's constraints - which is an expected behaviour, see picture #2.

Now when i reverse the situation - make the second (violet) TextView expand I'm not getting similar result - picture #3. As we can see the second TextView doesn't respect the first TextView constraints.

The other thing that I've also found is that if we replace the order of TextViews in our *.xml file as "TextView red -> TextView violet" to "TextView violet <- TextView red" while keeping the constraints it works properly - picture 4 (but the previous case ie fails again).

enter image description here

I've used the latest constraint layout libraries:

//    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0-alpha2'

And the layout:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <TextView
        android:background="#f00"
        android:id="@+id/a"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:textSize="50sp"
        android:text="a"
        app:layout_constraintHeight_default="wrap"
        app:layout_constraintBottom_toTopOf="@id/b"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        />


    <TextView
        android:background="#f0f"
        android:id="@+id/b"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:textSize="50sp"
        android:text="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
        app:layout_constraintHeight_default="wrap"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/a"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintVertical_chainStyle="packed"/
</androidx.constraintlayout.widget.ConstraintLayout>

If you do have an idea how to make two TextViews behave as in picture #1, #2 and #4 i would be very grateful.

2 Answers

You need to specify a minimum height constraint app:layout_constraintHeight_min="wrap" to both TextViews in order to make sure that both will at least wrap their content, in other words this will make any of the TextViews not to be greedy on one another.

Also this will keep both TextViews stretchable while maintaining the minimum height.

The only downside of this that both TextViews don't obey to the height constraints, you can see in below pic dashed line of height limits, also the top TextView text is cut. This is because both TextViews tends to wrap their content while keeping constraints at the same time.

enter image description here

In my trial, the padding is proportional to the size of the TextView and how big is the content of both of them.

A possible workaround to add padding at the top of top TextView, and at the Bottom of bottom Textivew

Another way to work on is to be strict to height constraint, and don't wrap height content by removing app:layout_constraintHeight_default="wrap" from both.

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/a"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#f00"
        android:paddingTop="0dp"
        android:text="a"
        android:textSize="50sp"
        app:layout_constraintBottom_toTopOf="@+id/b"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/b"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#f0f"
        android:paddingTop="0dp"
        android:text="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbzzzzzzzzzzzzzzz"
        android:textSize="50sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/a" />

</androidx.constraintlayout.widget.ConstraintLayout>

Edit: misunderstood wanted behavior. You have 2 options, use

app:layout_constraintHeight_min="minimumHeight"

or

app:layout_constraintHeight_percent="percentage/100"

Related