web-dev-qa-db-fra.com

Wrap_content la vue à l'intérieur d'un ConstraintLayout s'étend en dehors de l'écran

J'essaie de mettre en place une simple bulle de discussion en utilisant un ConstraintLayout. C'est ce que j'essaie de réaliser:

enter image description hereenter image description here

Cependant, wrap_content semble ne pas fonctionner correctement avec des contraintes. Il respecte les marges, mais ne calcule pas correctement l'espace disponible. Voici ma mise en page:

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

Cela se traduit comme suit:

enter image description here

J'utilise com.Android.support.constraint:constraint-layout:1.0.0-beta4.

Est-ce que je fais quelque chose de mal? Est-ce un bug ou juste un comportement non intuitif? Puis-je obtenir le comportement approprié en utilisant un ConstraintLayout (je sais que je peux utiliser d'autres dispositions, je pose une question à propos de ConstrainLayout plus précisément).

96
Marcin Jedynak

Obsolète: Voir meilleure réponse

Non, vous ne pouvez pas faire ce que vous voulez avec ConstraintLayout tel qu’il est aujourd’hui (1.0 beta 4):

  • wrap_content demande uniquement au widget de se mesurer lui-même, mais ne limitera pas son développement par rapport aux contraintes éventuelles
  • match_constraints (0dp) limitera la taille du widget en fonction des contraintes ... mais les fera correspondre même si wrap_content aurait été plus petit (votre premier exemple), ce qui n'est pas ce que vous voulez non plus.

Donc pour l'instant, vous n'avez pas de chance pour ce cas particulier: - /

Maintenant ... nous pensons ajouter des fonctionnalités supplémentaires à match_constraints pour traiter ce scénario exact (se comportant comme wrap_content à moins que la taille ne soit supérieure à la contrainte).

Je ne peux cependant pas promettre que cette nouvelle fonctionnalité sera disponible avant la version 1.0.

Edit : nous avons ajouté cette fonctionnalité dans la version 1.0 avec l'attribut app:layout_constraintWidth_default="wrap" (avec la largeur définie sur 0dp). Si défini, le widget aura la même taille que si vous utilisiez wrap_content, mais sera limité par des contraintes (c'est-à-dire qu'il ne s'étendra pas au-delà de celles-ci)

194
Nicolas Roard

Mis à jour (ConstraintLayout 1.1. +)

Utilisez app:layout_constrainedWidth="true" avec une largeur définie sur wrap_content

Auparavant (obsolète):

app:layout_constraintWidth_default="wrap" avec une largeur définie sur 0dp

161
Silvia H

Oui, comme mentionné dans la réponse donnée par Nikolas Roard vous devez ajouter app:layout_constraintWidth_default="wrap" et définir width à 0dp. Et pour aligner votre bulle à droite, vous devez définir 1.0 pour layout_constraintHorizontal_bias.

Voici le code source 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>

En conséquence, cela ressemble à:

enter image description here

18
Eugene Brusov

Comme les autres réponses déjà mentionnées, depuis ConstraintLayout 1.0, il est possible d'y parvenir, mais depuis la dernière version (1.1.x), ils ont changé la façon dont vous le faites.

Depuis la sortie de ConstraintLayout 1.1, les anciens attributs app:layout_constraintWidth_default="wrap" et app:layout_constraintHeight_default="wrap" sont désormais obsolètes .

Si vous souhaitez fournir un comportement wrap_content, tout en appliquant les contraintes sur votre vue, vous devez définir sa largeur et/ou sa hauteur sur wrap_content associé au app:layout_constrainedWidth=”true|false” et/ou app:layout_constrainedHeight=”true|false” attributs, comme indiqué sur la documentation :

WRAP_CONTENT: application de contraintes (ajouté en 1.1) Si une dimension est définie sur WRAP_CONTENT, dans les versions antérieures à 1.1, elles seront traitées comme une dimension littérale - ce qui signifie , les contraintes ne limiteront pas la dimension résultante. Bien qu'en général, cela soit suffisant (et plus rapide), dans certaines situations, vous pouvez utiliser WRAP_CONTENT tout en continuant à appliquer des contraintes pour limiter la dimension résultante. Dans ce cas, vous pouvez ajouter l'un des attributs correspondants:

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

En ce qui concerne la dernière version, au moment où j'ai répondu à cette question, ConstraintLayout est sur la version 1.1.2 .

8
Mauker

Deprecation of app:layout_constraintWidth_default text and its alternative

La réponse de @ [nicolas-roard sur app:layout_constraintWidth_default="wrap" et Android:layout_width="0dp" est maintenant OBSOLÈTE.

Allez-y et utilisez app:layout_constrainedWidth="true" et Android:layout_width="wrap_content".

La raison de la dépréciation, je ne sais pas. Mais sa droite dans le code source de ConstraintLayout

1
Bolaji