La vue Wrap_content dans une ConstraintLayout s’étend à l’extérieur de l’écran

J’essaie d’implémenter une simple bulle de discussion en utilisant un ConstraintLayout . C’est ce que j’essaie de réaliser:

entrer la description de l'image ici entrer la description de l'image ici

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

     

Cela rend comme suit:

entrer la description de l'image ici

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 bon comportement en utilisant un ConstraintLayout (je sais que je peux utiliser d’autres mises en page, je parle spécifiquement de ConstrainLayout ).

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, mais ne limitera pas son expansion aux contraintes éventuelles
  • match_constraints (0dp) limitera la taille du widget contre les 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, maintenant, vous n’avez pas de chance pour ce cas particulier: – /

Maintenant, nous envisageons d’append des capacités supplémentaires à match_constraints pour gérer ce scénario exact (se comporter comme wrap_content moins que la taille ne soit plus que les contraintes).

Je ne peux pas promettre que cette nouvelle fonctionnalité le fera avant la version 1.0.

Edit : nous avons ajouté cette fonctionnalité en 1.0 avec l’atsortingbut app:layout_constraintWidth_default="wrap" (avec la largeur définie sur 0dp). S’il est défini, le widget aura la même taille que s’il utilisait wrap_content, mais sera limité par des contraintes (c.-à-d. Qu’il ne se développera pas au-delà)

app:layout_constraintWidth_default="wrap" (with width set to 0dp) est maintenant obsolète .

Vous devez utiliser app:layout_constrainedWidth="true" avec la largeur définie sur wrap_content

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

Voici le code source final:

    

En conséquence, cela ressemble à:

entrer la description de l'image ici

Comme les autres réponses l’ont déjà dit, depuis ConstraintLayout 1.0, il est possible d’y parvenir, mais depuis la dernière version (1.1.x), ils ont changé votre façon de faire.

Depuis la sortie de ConstraintLayout 1.1, les anciennes app:layout_constraintWidth_default="wrap" et app:layout_constraintHeight_default="wrap" sont maintenant obsolètes .

Si vous voulez fournir un comportement wrap_content , mais que vous wrap_content toujours les contraintes sur votre View, vous devez définir sa largeur et / ou sa hauteur à wrap_content combiné avec l’ app:layout_constrainedWidth=”true|false” et / ou app:layout_constrainedHeight=”true|false” atsortingbuts, comme indiqué sur les documents :

WRAP_CONTENT: application de contraintes (Ajouté dans 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 que 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 vouloir utiliser WRAP_CONTENT, tout en continuant à appliquer des contraintes pour limiter la dimension résultante. Dans ce cas, vous pouvez append l’un des atsortingbuts suivants:

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

Quant à la dernière version, au moment où j’ai répondu à cette question, ConstraintLayout est sur la version 1.1.2 .

J’utilise celui-ci

 app:layout_constraintEnd_toEndOf="parent" 

Vous devriez remplacer

 android:layout_width="wrap_content" 

avec

 android:layout_width="match_parent" 

à partir de votre TextView, puis ajustez le remplissage et la marge en conséquence. J’ai mis à jour votre code,

   

Vous obtiendrez ce résultat entrer la description de l'image ici