Home » Android » android – Wrap_content view inside a ConstraintLayout stretches outside the screen

android – Wrap_content view inside a ConstraintLayout stretches outside the screen

Posted by: admin March 11, 2020 Leave a comment

Questions:

I am trying to implement a simple chat bubble using a ConstraintLayout. This is what I am trying to achieve:

enter image description here
enter image description here

However, wrap_content seem not to work properly with constraints. It respects the margins, but doesn’t calculate the available space properly. Here is my layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="wrap_content">

    <TextView
        android:id="@+id/chat_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0"
        tools:background="@drawable/chat_message_bubble"
        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum."
        android:layout_marginStart="64dp"
        android:layout_marginLeft="64dp"
        android:layout_marginEnd="32dp"
        android:layout_marginRight="32dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp" />
</android.support.constraint.ConstraintLayout>

This renders as follows:

enter image description here

I am using com.android.support.constraint:constraint-layout:1.0.0-beta4.

Am I doing something wrong? Is it a bug or just an unintuitive behavior? Can I achieve the proper behavior using a ConstraintLayout (I know I can use other layouts, I am asking about ConstrainLayout specifically).

How to&Answers:

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”.

Answer:

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"

Answer:

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

Answer:

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.

Answer:

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

Answer:

I use this one

app:layout_constraintEnd_toEndOf="parent"

Answer:

You should replace

android:layout_width="wrap_content"

with

android:layout_width="match_parent"

from your TextView and then adjust padding and margin accordingly.
I have updated your code,

<android.support.constraint.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="wrap_content">

<TextView
    android:id="@+id/chat_message"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="10dp"
    android:layout_marginLeft="60dp"
    android:layout_marginRight="10dp"
    android:layout_marginStart="60dp"
    android:layout_marginTop="8dp"
    android:padding="16dp"
    app:layout_constraintTop_toTopOf="parent"
    tools:background="#c9c7c7"
    tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum." />

You will get this result
enter image description here