androidx / constraintlayout

ConstraintLayout is an Android layout component which allows you to position and size widgets in a flexible way
Apache License 2.0
1.06k stars 177 forks source link

constrained width expands the view #713

Open WildOrangutan opened 1 year ago

WildOrangutan commented 1 year ago

Issue

When layout_constrainedWidth is set to true, it can expand parent layout.

Use case

I'm trying to achieve following layout. I want text_view to expand until it's limitied by size of view_2. image

But when layout_constrainedWidth is set, it expands whole parent: image

<?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="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@android:color/darker_gray">

    <View
        android:id="@+id/view_1"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:background="@android:color/holo_blue_dark"
        app:layout_constraintEnd_toStartOf="@id/text_view"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="@id/view_2"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:background="@android:color/holo_purple"
        android:ellipsize="end"
        android:maxLines="1"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="@id/view_2"
        app:layout_constraintStart_toEndOf="@id/view_1"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="@tools:sample/lorem/random" />

    <View
        android:id="@+id/view_2"
        android:layout_width="200dp"
        android:layout_height="20dp"
        android:background="@android:color/holo_red_dark"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/view_1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Versions

androidx.constraintlayout:constraintlayout:2.1.4

jafu888 commented 1 year ago

wrap_content In text_view means the size of the text wins. Why are you not using 0dp ?

WildOrangutan commented 1 year ago

If I use 0dp, text_view will fill all the available space, which I don't want.

I want view_1 and text_view to be packed together and centered (1st image), but be also be able to expand like in 2nd image. The only undesired effect is that parent layout expands for some reason (grey area).

jafu888 commented 1 year ago

Try this: android:layout_width="0dp" and app:layout_constraintWidth_max="wrap"

        <TextView
            android:id="@+id/text_view"
            android:layout_width="0dp"
            android:layout_height="20dp"
            android:background="@android:color/holo_purple"
            android:ellipsize="end"
            android:maxLines="1"
            android:textColor="@color/white"
            app:layout_constraintWidth_max="wrap"
            app:layout_constraintEnd_toEndOf="@id/view_2"
            app:layout_constraintStart_toEndOf="@id/view_1"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@tools:sample/lorem/random" />

It should give you want you want

WildOrangutan commented 1 year ago

Yeah, that has the desired effect.

I'm confused tough, shouldn't my initial code also work? At least I gathered from documentation, that this should be possible.

jafu888 commented 1 year ago

This has to do with priorities - who wins the "fight between wrap and constraints" in various scenarios. Both satisfy the constraints Constraints do not want to be negative.
width=wrap + constrainedWidth=true - wrap wins if at all possible width=0dp + default=wrap - wrap wins after all other constraints are satisfied

It is hard to explain and ends up being super confusing in the documentation unless you encounter your type of problem. Adding it to the documentation would be a long confusing section to explain a corner case. We will update the documentation with a line: (Consider using width=0dp & default=wrap to adjust the priorities)

Some percentage of people approach the problem from with=0dp and never think about the subtlety. Some start with width=wrap encounter the issue try width=0dp, default=wrap Some like you get stuck on it.