Die Wrap_content-Ansicht innerhalb eines ConstraintLayout erstreckt sich außerhalb des Bildschirms

132

Ich versuche eine einfache Chat-Blase mit a zu implementieren ConstraintLayout. Das versuche ich zu erreichen:

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Allerdings wrap_contentscheint nicht richtig mit Einschränkungen zu arbeiten. Es berücksichtigt die Ränder, berechnet jedoch den verfügbaren Speicherplatz nicht richtig. Hier ist mein 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>

Dies ergibt Folgendes:

Geben Sie hier die Bildbeschreibung ein

Ich benutze com.android.support.constraint:constraint-layout:1.0.0-beta4.

Mache ich etwas falsch? Ist es ein Fehler oder nur ein unintuitives Verhalten? Kann ich mit a das richtige Verhalten erreichen ConstraintLayout(ich weiß, dass ich andere Layouts verwenden kann, nach denen ich ConstrainLayoutspeziell frage).

Marcin Jedynak
quelle
Können Sie die Textansicht zusammen mit dem übergeordneten Einschränkungslayout veröffentlichen? Wie Sie wissen, haben Attribute des Elternlayouts einen großen Einfluss auf das Kind
Mohammed Atif
Übrigens, in Ihrem Fall denke ich, dass horizontale Voreingenommenheit der Schuldige ist. versuchen Sie, Layout rechts von und Voreingenommenheit zu entfernen
Mohammed Atif
1
Eine horizontale Vorspannung ist erforderlich, andernfalls, wenn die Blase zentriert ist. Ohne Layout von rechts nach rechts wird der rechte Rand nicht berücksichtigt, was wir nicht wollen. Ich habe versucht, sie zu entfernen, wie Sie geraten haben, aber es hat nicht geholfen.
Marcin Jedynak
1
Problem ist sicher horizontale Vorspannung 0. Ich werde nach möglichen Lösungen suchen und sie so schnell wie möglich veröffentlichen, da ich auch mit etwas Ähnlichem am Einschränkungslayout arbeite.
Mohammed Atif
1
@nmu Chat Blase kommt von tools:background="@drawable/chat_message_bubble". Um es zu implementieren, müssen Sie die Datei chat_message_bubble.xml in einem zeichnbaren Ordner erstellen und dann den folgenden Code hinzufügen: <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FB4382"/> <corners android:radius="10dip"/> </shape>
Eugene Brusov

Antworten:

242

Veraltet: Bessere Antwort sehen

Nein, Sie können mit ConstraintLayout nicht das tun, was Sie heute wollen (1.0 Beta 4):

  • wrap_content fordert das Widget nur auf, sich selbst zu messen, beschränkt seine Erweiterung jedoch nicht auf eventuelle Einschränkungen
  • match_constraints(0DP) wird die Größe des Widgets gegen die Zwänge begrenzen ... aber wird sie auch passen , wenn wrap_contentwäre geringer gewesen (Ihr erstes Beispiel), das ist nicht das, was Sie wollen entweder.

Im Moment haben Sie also kein Glück für diesen speziellen Fall: - /

Jetzt ... denken wir darüber nach, zusätzliche Funktionen hinzuzufügen match_constraints, um genau dieses Szenario zu bewältigen (so, als wrap_contentob die Größe nicht mehr als die Einschränkungen ist).

Ich kann nicht versprechen, dass diese neue Funktion es vor der Version 1.0 schaffen wird.

Bearbeiten : Wir haben diese Funktion in 1.0 mit dem Attribut app:layout_constraintWidth_default="wrap"hinzugefügt (mit einer Breite von 0dp). Wenn festgelegt, hat das Widget die gleiche Größe wie bei Verwendung von wrap_content, wird jedoch durch Einschränkungen eingeschränkt (dh es wird nicht darüber hinaus erweitert).

Update Jetzt sind diese Tags veraltet. Verwenden Sie stattdessen layout_width = "WRAP_CONTENT" und layout_constrainedWidth = "true".

Nicolas Roard
quelle
1
Das ist ein super Problem für mich. Ich kann TextView derzeit nicht mit zusammengesetzten Zeichen verwenden, da sich match_constraintsdas Zusammensetzen auf zusammengesetzte Zeichen ganz rechts befindet, selbst wenn sehr kurzer Text vorhanden ist.
Paul Woitaschek
2
@NicolasRoard: Kannst du mir beim Einschränkungslayout helfen? Ich habe ein Bild in der oberen Hälfte mit einer Richtlinie von 0,4 und Inhalt unten, aber wenn ich das Einschränkungslayout auf wrap_content setze, werden nur 0,4 des Bildschirms (und die Hälfte des Bildschirms) ausgewählt Textansichten unten sind nicht sichtbar), ich habe auch verwendet app:layout_constraintWidth_default="wrap", und v1.0.2 der Bibliothek, aber es hilft nicht
Rat-a-tat-a-tat Ratatouille
3
app: layout_constraintWidth_default = "Wrap" mit Breite, da 0dp es gut macht!
Tunji_D
11
Dies sollte EXPLICIT in der Dokumentation / Anleitung sein.
SQLiteNoob
6
Sollte die Bearbeitung eine größere Bedeutung haben? Art geht unter dem Original verloren. Schätzen Sie die Antwort. Danke @NicolasRoard.
Tom Howard
276

Aktualisiert (ConstraintLayout 1.1. +)

Verwenden Sie app:layout_constrainedWidth="true"mitandroid:layout_width="wrap_content"

Zuvor (veraltet):

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

Silvia H.
quelle
5
Richtig, seit ConstraintLayout 1.1.0 Beta 2 glaube ich. androidstudio.googleblog.com/2017/10/…
Fifer Sheep
2
Dies jetzt in der Version 1.1: medium.com/google-developers/…
Esdras Lopez
Liebe Stackoverflow! danke das hat mir geholfen! Behalten Sie den Wrap-Inhalt bei, aber gehen Sie niemals über die Einschränkung hinaus! #TIL
Dennis Anderson
Was für eine Antwort, wusste nicht, dass es das gibt! Danke Mann, nach 2 Stunden Spiel mit Alternativen hat das geklappt!
dev2505
23

Ja, wie in der Antwort von Nikolas Roard erwähnt , sollten Sie app:layout_constraintWidth_default="wrap"die Breite auf 0 dp hinzufügen und einstellen. Und um Ihre Blase richtig auszurichten, sollten Sie 1.0 für einstellen layout_constraintHorizontal_bias.

Hier ist der endgültige Quellcode:

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

Als Ergebnis sieht es so aus:

Geben Sie hier die Bildbeschreibung ein

Eugene Brusov
quelle
Ich denke, das liegt daran, dass OP eine kleine Blase links und Ihre rechts haben will, was die Anforderungen ändert
Waza_Be
2
wichtiger Teil hier istapp:layout_constraintHorizontal_bias="1.0"
Lester
9

Wie die anderen bereits erwähnten Antworten, ist es seit ConstraintLayout 1.0 möglich, dies zu erreichen, aber seit der neuesten Version (1.1.x) haben sie Ihre Vorgehensweise geändert.

Seit der Veröffentlichung von ConstraintLayout 1.1 sind das alte app:layout_constraintWidth_default="wrap"und die app:layout_constraintHeight_default="wrap"Attribute veraltet .

Wenn Sie ein zur Verfügung stellen mögen wrap_contentVerhalten, aber immer noch die Einschränkungen auf Ihrer Ansicht durchzusetzen, sollten Sie die Breite und / oder Höhe auf , wrap_contentkombiniert mit dem app:layout_constrainedWidth=”true|false”und / oder app:layout_constrainedHeight=”true|false”Attribute, wie gesagt auf der Dokumentation :

WRAP_CONTENT: Erzwingen von Einschränkungen (in 1.1 hinzugefügt) Wenn eine Dimension auf WRAP_CONTENT festgelegt ist, werden sie in Versionen vor 1.1 als Literaldimension behandelt. Dies bedeutet, dass Einschränkungen die resultierende Dimension nicht einschränken. Während dies im Allgemeinen ausreicht (und schneller ist), möchten Sie in einigen Situationen möglicherweise WRAP_CONTENT verwenden, aber weiterhin Einschränkungen erzwingen, um die resultierende Dimension zu begrenzen. In diesem Fall können Sie eines der entsprechenden Attribute hinzufügen:

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

In Bezug auf die neueste Version befindet sich ConstraintLayout zum Zeitpunkt meiner Beantwortung in Version 1.1.2 .

Mauker
quelle
3

Veraltete App: layout_constraintWidth_default Text und seine Alternative

@ nicolas-roards Antwort von app:layout_constraintWidth_default="wrap"und android:layout_width="0dp"ist jetzt DEPRECATED .

Gehen Sie voran und verwenden Sie app:layout_constrainedWidth="true"und android:layout_width="wrap_content".

Den Grund für die Abwertung weiß ich nicht. Aber es ist richtig im Quellcode von ConstraintLayout

Bolaji
quelle
-7

Ich benutze diesen

app:layout_constraintEnd_toEndOf="parent"
jsHate
quelle
Wie ist das und die Frage von OP? Wie wird dieser Inhalt umbrochen?
Alex
-8

Sie sollten ersetzen

android:layout_width="wrap_content"

mit

android:layout_width="match_parent"

aus Ihrer Textansicht und passen Sie dann Polsterung und Rand entsprechend an. Ich habe Ihren Code aktualisiert.

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

Sie erhalten dieses Ergebnis Geben Sie hier die Bildbeschreibung ein

Mehul
quelle
Sie sollten vermeiden, "match_parent" für eine Ansicht in einem ConstraintLayout zu verwenden. Schauen Sie sich "Note" hier an
Eugene Brusov