Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

constrained width expands the view #713

Open
WildOrangutan opened this issue Sep 9, 2022 · 5 comments
Open

constrained width expands the view #713

WildOrangutan opened this issue Sep 9, 2022 · 5 comments
Labels
bug Something isn't working

Comments

@WildOrangutan
Copy link

WildOrangutan commented Sep 9, 2022

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

@WildOrangutan WildOrangutan added the bug Something isn't working label Sep 9, 2022
@WildOrangutan WildOrangutan changed the title constrained with expands the view constrained width expands the view Sep 9, 2022
@jafu888
Copy link
Collaborator

jafu888 commented Sep 10, 2022

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

@WildOrangutan
Copy link
Author

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
Copy link
Collaborator

jafu888 commented Sep 12, 2022

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
Copy link
Author

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
Copy link
Collaborator

jafu888 commented Nov 28, 2022

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.

jrguzman-ms pushed a commit to msft-mirror-aosp/platform.frameworks.base that referenced this issue Mar 15, 2023
is lack of space.

Previously:
There was a chain [date]-[space]-[status icons]-[battery]. That's why we should add bias and space to make it working.
But there're several problems with this:
 1) app:layout_width="WRAP_CONTENT" + app:layout_constrainedWidth=”true" != app:layout_width="0dp" + app:layout_constraintWidth_default="wrap". The first one gets view expanded like it's MATCH_PARENT.
 2) I've found out that wrapping views in constraint layout 2.0.0 may not always work as expected with app:layout_constrainedWidth=”true" (the view get's stretched as it's match_parent). layout_constraintWidth_max="wrap" should've help with this, but motion layout can't parse this attribute in constraint set. That's why my solution is to reimplement the layout a little bit
This behavior is reported here: androidx/constraintlayout#713

Now:
[date] and [battery] are constrained to the sides and [status icons] occupy the whole space between them.
[date] is always WRAP_CONTENT because there's always some space and we want to show it.
[battery] and [status icons] are wrap content with constraints restrictions to make them fill all the space left

Test: manual: phone + tablet
Fixes: 260364389
Change-Id: I4d54b795cc4e96f6c204f2f00aff7607572d9aa3
(cherry picked from commit 675ff0f)
Merged-In: I4d54b795cc4e96f6c204f2f00aff7607572d9aa3
Dhruvesh16 pushed a commit to ProjectBlaze/frameworks_base that referenced this issue Jun 17, 2023
is lack of space.

Previously:
There was a chain [date]-[space]-[status icons]-[battery]. That's why we should add bias and space to make it working.
But there're several problems with this:
 1) app:layout_width="WRAP_CONTENT" + app:layout_constrainedWidth=”true" != app:layout_width="0dp" + app:layout_constraintWidth_default="wrap". The first one gets view expanded like it's MATCH_PARENT.
 2) I've found out that wrapping views in constraint layout 2.0.0 may not always work as expected with app:layout_constrainedWidth=”true" (the view get's stretched as it's match_parent). layout_constraintWidth_max="wrap" should've help with this, but motion layout can't parse this attribute in constraint set. That's why my solution is to reimplement the layout a little bit
This behavior is reported here: androidx/constraintlayout#713

Now:
[date] and [battery] are constrained to the sides and [status icons] occupy the whole space between them.
[date] is always WRAP_CONTENT because there's always some space and we want to show it.
[battery] and [status icons] are wrap content with constraints restrictions to make them fill all the space left

Test: manual: phone + tablet
Fixes: 260364389
Change-Id: I4d54b795cc4e96f6c204f2f00aff7607572d9aa3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants