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 ifwrap_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:
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:
@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