La vista Wrap_content dentro de ConstraintLayout se extiende fuera de la pantalla

132

Estoy tratando de implementar una burbuja de chat simple usando a ConstraintLayout. Esto es lo que estoy tratando de lograr:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Sin embargo, wrap_contentparece que no funciona correctamente con restricciones. Respeta los márgenes, pero no calcula el espacio disponible correctamente. Aquí está mi diseño:

<?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>

Esto se traduce de la siguiente manera:

ingrese la descripción de la imagen aquí

Estoy usando com.android.support.constraint:constraint-layout:1.0.0-beta4.

¿Estoy haciendo algo mal? ¿Es un error o simplemente un comportamiento poco intuitivo? ¿Puedo lograr el comportamiento adecuado usando un ConstraintLayout(sé que puedo usar otros diseños, estoy preguntando ConstrainLayoutespecíficamente).

Marcin Jedynak
fuente
¿Puedes publicar la vista de texto junto con su diseño de restricción principal? como saben, los atributos del diseño de los padres tienen un gran impacto en el niño
Mohammed Atif
Por cierto, en su caso, supongo que el sesgo horizontal es el culpable. trate de eliminar el derecho a la derecha y el sesgo
Mohammed Atif
1
El sesgo horizontal es necesario, de lo contrario si la burbuja está centrada. Sin un diseño de derecha a derecha, el margen derecho no se tendrá en cuenta, que no es lo que queremos. Traté de eliminarlos, como me aconsejaste, pero no sirvió de nada.
Marcin Jedynak
1
El problema es el sesgo horizontal 0 seguro. Comprobaré las posibles soluciones y las publicaré lo antes posible, ya que también estoy trabajando con algo similar en el diseño de restricciones.
Mohammed Atif
1
@nmu burbuja de chat proviene tools:background="@drawable/chat_message_bubble". Para implementarlo, debe crear el archivo chat_message_bubble.xml en una carpeta dibujable y luego agregar este código: <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FB4382"/> <corners android:radius="10dip"/> </shape>
Eugene Brusov

Respuestas:

242

Anticuado: Ver mejor respuesta

No, no puede hacer lo que quiere con ConstraintLayout tal como está hoy (1.0 beta 4):

  • wrap_content solo le pide al widget que se mida a sí mismo, pero no limitará su expansión contra restricciones eventuales
  • match_constraints(0DP) será limitar el tamaño del widget en contra de las limitaciones ... pero coincidirá con ellos, incluso si wrap_contenthubiera sido más pequeño (el primer ejemplo), lo cual no es lo que quiere tampoco.

Así que en este momento, no tienes suerte para ese caso en particular: - /

Ahora ... estamos pensando en agregar capacidades adicionales match_constraintspara lidiar con este escenario exacto (comportándonos como wrap_contentsi el tamaño no fuera más que las restricciones).

Sin embargo, no puedo prometer que esta nueva característica llegará antes de la versión 1.0.

Editar : agregamos esta capacidad en 1.0 con el atributo app:layout_constraintWidth_default="wrap"(con el ancho establecido en 0dp). Si se establece, el widget tendrá el mismo tamaño que si se utiliza wrap_content, pero estará limitado por restricciones (es decir, no se expandirá más allá de ellas)

Actualizar Ahora esas etiquetas están en desuso, en su lugar use layout_width = "WRAP_CONTENT" y layout_constrainedWidth = "true".

Nicolas Roard
fuente
1
Eso es un gran problema para mí. No puedo usar TextView con elementos dibujables compuestos en este momento porque si lo configuro en match_constraintsel compuesto, el dibujable estará a la derecha, incluso si hay texto muy corto.
Paul Woitaschek
2
@NicolasRoard: ¿pueden ayudarme con el diseño de restricción? Tengo una imagen en la mitad superior con una directriz de 0.4 y contenido a continuación, pero cuando configuro el diseño de restricción en wrap_content, solo selecciona 0.4 de la pantalla (y la mitad de la pantalla). las vistas de texto a continuación no son visibles), yo app:layout_constraintWidth_default="wrap"también lo utilicé , y la v1.0.2 de la biblioteca, pero no ayuda
Rat-a-tat-a-tat Ratatouille
3
app: layout_constraintWidth_default = "wrap" con ancho como 0dp lo hace muy bien!
Tunji_D
11
Esto debe ser EXPLÍCITO en la documentación / instrucciones.
SQLiteNoob
66
¿Debería la edición moverse para tener mayor importancia? Se pierde un poco debajo del original. Agradezco la respuesta. Gracias @NicolasRoard.
Tom Howard
276

Actualizado (ConstraintLayout 1.1. +)

Usar app:layout_constrainedWidth="true"conandroid:layout_width="wrap_content"

Anteriormente (en desuso):

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

Silvia H
fuente
55
Es cierto, desde ConstraintLayout 1.1.0 beta 2, creo. androidstudio.googleblog.com/2017/10/…
Fifer Sheep
2
Esto ahora en la versión 1.1: medium.com/google-developers/…
Esdras Lopez
amor stackoverflow! gracias esto me ayudo! mantenga el contenido de la envoltura, pero nunca vaya más allá de la restricción. #TIL
Dennis Anderson
¡Qué respuesta, no sabía que existía! Gracias, después de 2 horas de jugar con alternativas, ¡funcionó de maravilla!
dev2505
23

Sí, como se menciona en la respuesta dada por Nikolas Roard , debe agregar app:layout_constraintWidth_default="wrap"y establecer el ancho en 0dp. Y para alinear su burbuja correctamente, debe establecer 1.0 para layout_constraintHorizontal_bias.

Aquí está el código fuente final:

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

Como resultado se ve así:

ingrese la descripción de la imagen aquí

Eugene Brusov
fuente
Creo que es porque OP quiere una pequeña burbuja a la izquierda y la suya es la derecha, lo que cambia los requisitos
Waza_Be
2
Lo importante aquí esapp:layout_constraintHorizontal_bias="1.0"
Lester
9

Como las otras respuestas ya dijeron, desde ConstraintLayout 1.0 es posible lograr eso, pero a partir de la versión más reciente (1.1.x) han cambiado la forma en que lo haces.

Desde el lanzamiento de ConstraintLayout 1.1, los atributos antiguos app:layout_constraintWidth_default="wrap"y ahora están en desuso .app:layout_constraintHeight_default="wrap"

Si desea proporcionar un wrap_contentcomportamiento, pero aún así imponer las restricciones en su Vista, debe establecer su ancho y / o altura para que se wrap_contentcombinen con los atributos app:layout_constrainedWidth=”true|false”y / o app:layout_constrainedHeight=”true|false”, como se indica en los documentos :

WRAP_CONTENT: imponer restricciones (agregado en 1.1) Si una dimensión se establece en WRAP_CONTENT, en las versiones anteriores a 1.1 se tratarán como una dimensión literal, lo que significa que las restricciones no limitarán la dimensión resultante. Si bien, en general, esto es suficiente (y más rápido), en algunas situaciones, es posible que desee utilizar WRAP_CONTENT, pero seguir aplicando restricciones para limitar la dimensión resultante. En ese caso, puede agregar uno de los atributos correspondientes:

aplicación: layout_constrainedWidth = ”true | false” aplicación: layout_constrainedHeight = ”true | false”

En cuanto a la última versión, cuando he respondido esto, ConstraintLayout está en la versión 1.1.2 .

Mauker
fuente
3

Desuso de la aplicación: diseño_constraintWidth_default text y su alternativa

La respuesta de @ nicolas-roard de app:layout_constraintWidth_default="wrap"y android:layout_width="0dp"ahora está DEPRECADA .

Adelante, usa app:layout_constrainedWidth="true"y android:layout_width="wrap_content".

La razón de la depreciación, no lo sé. Pero está justo en el código fuente de ConstraintLayout

Bolaji
fuente
-7

Yo uso este

app:layout_constraintEnd_toEndOf="parent"
jsHate
fuente
¿Cómo funciona esto y la pregunta de OP? ¿Cómo envuelve este contenido?
Alex
-8

Deberías reemplazar

android:layout_width="wrap_content"

con

android:layout_width="match_parent"

desde su TextView y luego ajuste el relleno y el margen en consecuencia. He actualizado tu código,

<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." />

Obtendrás este resultado ingrese la descripción de la imagen aquí

Mehul
fuente
Debe evitar usar "match_parent" para cualquier vista en un ConstraintLayout. Mira "Nota" aquí
Eugene Brusov