La vista Wrap_content all'interno di un Vincolo vincolo si estende all'esterno dello schermo


132

Sto cercando di implementare una semplice bolla di chat usando a ConstraintLayout. Questo è ciò che sto cercando di ottenere:

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Tuttavia, wrap_contentsembra non funzionare correttamente con i vincoli. Rispetta i margini, ma non calcola correttamente lo spazio disponibile. Ecco il mio 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>

Questo rende come segue:

inserisci qui la descrizione dell'immagine

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

Sto facendo qualcosa di sbagliato? È un bug o solo un comportamento non intuitivo? Posso ottenere il comportamento corretto usando un ConstraintLayout(so di poter usare altri layout, chiedo in ConstrainLayoutparticolare).


puoi pubblicare la vista di testo insieme al layout del vincolo principale? come sapete, gli attributi del layout genitore hanno un grande impatto sul bambino
Mohammed Atif,

A proposito, nel tuo caso immagino che il colpevole sia il pregiudizio orizzontale. prova a rimuovere layoutright a destra di e bias
Mohammed Atif

1
È necessario un orientamento orizzontale, altrimenti se la bolla è centrata. Senza layout da destra a destra il margine giusto non verrà preso in considerazione, il che non è ciò che vogliamo. Ho provato a rimuoverli, come mi hai consigliato, ma non ha aiutato.
Marcin Jedynak,

1
il problema è sicuramente il bias orizzontale 0. Cercherò le possibili soluzioni e la pubblicherò al più presto, poiché sto anche lavorando a qualcosa di simile sul layout dei vincoli.
Mohammed Atif,

1
La bolla di chat di @nmu viene tools:background="@drawable/chat_message_bubble". Per implementarlo devi creare il file chat_message_bubble.xml nella cartella disegnabile quindi aggiungere questo codice: <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FB4382"/> <corners android:radius="10dip"/> </shape>
Eugene Brusov

Risposte:


242

Non aggiornato: vedi una risposta migliore

No, non puoi fare quello che vuoi con ConstraintLayout come è oggi (1.0 beta 4):

  • wrap_content chiede solo al widget di misurarsi, ma non limiterà la sua espansione a fronte di eventuali vincoli
  • match_constraints(0DP) sarà limitare le dimensioni del widget contro i vincoli ... ma loro anche se corrisponderà wrap_contentsarebbe stato più piccolo (il vostro primo esempio), che non è quello che si vuole sia.

Quindi in questo momento, sei sfortunato per quel caso particolare: - /

Ora ... stiamo pensando di aggiungere ulteriori capacità per match_constraintsaffrontare questo scenario esatto (comportandoci come wrap_contentse la dimensione non fosse superiore ai vincoli).

Non posso promettere che questa nuova funzionalità ce la farà prima della versione 1.0.

Modifica : abbiamo aggiunto questa funzionalità in 1.0 con l'attributo app:layout_constraintWidth_default="wrap"(con larghezza impostata su 0dp). Se impostato, il widget avrà le stesse dimensioni di se si utilizza wrap_content, ma sarà limitato da vincoli (ovvero non si espanderà oltre questi)

Aggiorna Ora quei tag sono obsoleti, invece usa layout_width = "WRAP_CONTENT" e layout_constrainedWidth = "true".


1
Questo è un super problema per me. Non riesco a usare TextView con drawable composti in questo momento perché se lo imposto match_constraintssul drawable composto sarà sulla destra, anche se c'è un testo molto breve.
Paul Woitaschek,

2
@NicolasRoard: puoi aiutarmi con il layout dei vincoli, ho un'immagine nella metà superiore con una linea guida di 0.4 e contenuto sotto, ma quando imposto il layout del vincolo su wrap_content, seleziona solo 0,4 dello schermo (e metà del le seguenti visualizzazioni di testo non sono visibili), app:layout_constraintWidth_default="wrap"anch'io ho usato , e v1.0.2 della libreria ma non aiuta
Rat-a-tat-a-tat Ratatouille,

3
app: layout_constraintWidth_default = "avvolgere" con larghezza come 0dp lo fa bene!
Tunji_D,

11
questo dovrebbe essere ESPLICITO nella documentazione / istruzioni.
SQLiteNoob,

6
Se la modifica mossa per avere maggior risalto? Un po 'si perde sotto l'originale. Apprezzo la risposta. Grazie @NicolasRoard.
Tom Howard,

276

Aggiornato (ConstraintLayout 1.1. +)

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

Precedentemente (obsoleto):

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


5
È vero, da ConstraintLayout 1.1.0 beta 2, credo. androidstudio.googleblog.com/2017/10/…
Fifer Sheep

2
Questo ora nella versione 1.1: medium.com/google-developers/…
Esdras Lopez,

amore stackoverflow! grazie questo mi ha aiutato! mantenere il contenuto a capo, ma non andare mai oltre il vincolo! #TIL
Dennis Anderson,

Che risposta, non sapevo che esistesse! Grazie amico, dopo 2 ore di gioco con alternative questo ha funzionato a meraviglia!
dev2505

23

Sì, come menzionato nella risposta data da Nikolas Roard , dovresti aggiungere app:layout_constraintWidth_default="wrap"e impostare la larghezza su 0dp. E per allineare la bolla a destra dovresti impostare 1.0 per layout_constraintHorizontal_bias.

Ecco il codice sorgente finale:

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

Di conseguenza sembra:

inserisci qui la descrizione dell'immagine


Penso che sia perché OP vuole una piccola bolla a sinistra e la tua è giusta, il che cambia i requisiti
Waza_Be

2
la parte importante qui èapp:layout_constraintHorizontal_bias="1.0"
Lester,

9

Come hanno già detto le altre risposte, da ConstraintLayout 1.0 è possibile ottenerlo, ma dalla versione più recente (1.1.x) hanno cambiato il modo in cui lo fai.

Dal rilascio di ConstraintLayout 1.1, il vecchio app:layout_constraintWidth_default="wrap"e gli app:layout_constraintHeight_default="wrap"attributi sono ora obsoleti .

Se si desidera fornire un wrap_contentcomportamento, ma applicare comunque i vincoli sulla vista, è necessario impostarne la larghezza e / o l'altezza in modo da wrap_contentcombinarli con gli attributi app:layout_constrainedWidth=”true|false”e / o app:layout_constrainedHeight=”true|false”, come indicato nei documenti :

WRAP_CONTENT: vincoli di applicazione (aggiunti in 1.1) Se una dimensione è impostata su WRAP_CONTENT, nelle versioni precedenti alla 1.1 verranno trattate come una dimensione letterale, ovvero i vincoli non limiteranno la dimensione risultante. Mentre in generale questo è abbastanza (e più veloce), in alcune situazioni, potresti voler usare WRAP_CONTENT, ma continuare a imporre vincoli per limitare la dimensione risultante. In tal caso, puoi aggiungere uno degli attributi corrispondenti:

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

Per quanto riguarda l'ultima versione, quando ho risposto, ConstraintLayout è sulla versione 1.1.2 .


3

Deprecazione dell'app: layout_constraintWidth_default text e la sua alternativa

La risposta di @ nicolas-roard di app:layout_constraintWidth_default="wrap"e android:layout_width="0dp"ora è DEPRECATA .

Vai avanti e usa app:layout_constrainedWidth="true"e android:layout_width="wrap_content".

Il motivo della deprecazione, non lo so. Ma è proprio nel codice sorgente di ConstraintLayout


-7

Io uso questo

app:layout_constraintEnd_toEndOf="parent"

come fa questa domanda di OP? come si avvolge il contenuto?
Alex

-8

Dovresti sostituire

android:layout_width="wrap_content"

con

android:layout_width="match_parent"

dal tuo TextView e quindi regolare il riempimento e il margine di conseguenza. Ho aggiornato il tuo codice,

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

Otterrai questo risultato inserisci qui la descrizione dell'immagine


Dovresti evitare di usare "match_parent" per qualsiasi vista in un ConstraintLayout. Guarda "Note" qui
Eugene Brusov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.