Wrap_content view inside a ConstraintLayout stretches outside the screen

Solution 1:

Updated (ConstraintLayout 1.1.+)

Use app:layout_constrainedWidth="true" with android:layout_width="wrap_content"

Previously (deprecated):

app:layout_constraintWidth_default="wrap" with android:layout_width="0dp"

Solution 2:

Outdated: See better answer

No, you cannot do what you want with ConstraintLayout as it is today (1.0 beta 4):

  • wrap_content only asks the widget to measure itself, but won't limit its expansion against eventual constraints
  • match_constraints (0dp) will limit the size of the widget against the constraints... but will match them even if wrap_content would have been smaller (your first example), which isn't what you want either.

So right now, you are out of luck for that particular case :-/

Now... we are thinking about adding extra capabilities to match_constraints to deal with this exact scenario (behaving as wrap_content unless the size ends being more than the constraints).

I cannot promise that this new feature will make it before the 1.0 release though.

Edit: we did add this capability in 1.0 with the attribute app:layout_constraintWidth_default="wrap" (with width set to 0dp). If set, the widget will have the same size as if using wrap_content, but will be limited by constraints (i.e. it won't expand beyond them)

Update Now those tags are deprecated, instead use layout_width="WRAP_CONTENT" and layout_constrainedWidth="true".

Solution 3:

Yep, as mentioned in answer given by Nikolas Roard you should add app:layout_constraintWidth_default="wrap" and set width to 0dp. And to align your bubble right you should set 1.0 for layout_constraintHorizontal_bias.

Here's the final source code:

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

    <TextView
        android:id="@+id/chat_message"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginStart="64dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@drawable/chat_message_bubble"
        android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum." />

</android.support.constraint.ConstraintLayout>

As a result it looks like:

enter image description here

Solution 4:

Like the other answers already said, since ConstraintLayout 1.0 it's possible to achieve that, but as of the newest release (1.1.x) they've changed how you do it.

Since the release of ConstraintLayout 1.1 the old app:layout_constraintWidth_default="wrap" and app:layout_constraintHeight_default="wrap" attributes are now deprecated.

If you want to provide a wrap_content behavior, but still enforce the constraints on your View, you should set its width and/or height to wrap_content combined with the app:layout_constrainedWidth=”true|false” and/or app:layout_constrainedHeight=”true|false” attributes, as stated on the docs:

WRAP_CONTENT : enforcing constraints (Added in 1.1) If a dimension is set to WRAP_CONTENT, in versions before 1.1 they will be treated as a literal dimension -- meaning, constraints will not limit the resulting dimension. While in general this is enough (and faster), in some situations, you might want to use WRAP_CONTENT, yet keep enforcing constraints to limit the resulting dimension. In that case, you can add one of the corresponding attribute:

app:layout_constrainedWidth=”true|false” app:layout_constrainedHeight=”true|false”

As for the latest release, by the time I've answered this, ConstraintLayout is on version 1.1.2.

Solution 5:

Deprecation of app:layout_constraintWidth_default text and its alternative

@nicolas-roard's answer of app:layout_constraintWidth_default="wrap" and android:layout_width="0dp" is now DEPRECATED.

Go ahead and use app:layout_constrainedWidth="true" and android:layout_width="wrap_content".

The reason for deprecation, I dont know. But its right in the source code of ConstraintLayout