Представление Wrap_content внутри ConstraintLayout простирается за пределы экрана

Я пытаюсь реализовать простой чат с помощью ConstraintLayout, Вот чего я пытаюсь добиться:

Тем не мение, wrap_content кажется, не работает должным образом с ограничениями. Он учитывает поля, но не правильно рассчитывает доступное пространство. Вот мой макет:

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

Это выглядит следующим образом:

я использую com.android.support.constraint:constraint-layout:1.0.0-beta4,

Я делаю что-то неправильно? Это ошибка или просто не интуитивное поведение? Могу ли я добиться правильного поведения, используя ConstraintLayout (Я знаю, что могу использовать другие макеты, я спрашиваю о ConstrainLayout в частности).

6 ответов

Решение

Устаревший: см. Лучший ответ

Нет, вы не можете делать то, что вы хотите с ConstraintLayout, как сегодня (1.0 beta 4):

  • wrap_content только просит виджет измерить себя, но не будет ограничивать его расширение против возможных ограничений
  • match_constraints (0dp) будет ограничивать размер виджета в зависимости от ограничений... но будет соответствовать им, даже если wrap_content было бы меньше (ваш первый пример), чего вы тоже не хотите.

Так что сейчас вам не повезло в этом конкретном случае:-/

Теперь... мы думаем о добавлении дополнительных возможностей match_constraints иметь дело с этим точным сценарием (ведя себя как wrap_content если размер не будет больше ограничений).

Я не могу обещать, что эта новая функция появится до версии 1.0.

Изменить: мы добавили эту возможность в 1.0 с атрибутом app:layout_constraintWidth_default="wrap" (с шириной, установленной в 0dp). Если установлено, виджет будет иметь тот же размер, что и при использовании wrap_content, но будет ограничен ограничениями (то есть не будет выходить за их пределы)

app:layout_constraintWidth_default="wrap" (with width set to 0dp) сейчас устарела.

Вы должны использовать app:layout_constrainedWidth="true" с шириной, установленной вместо wrap_content

Да, как уже упоминалось в ответе Nicolas Roard, вы должны добавить app:layout_constraintWidth_default="wrap" и установите ширину 0dp. И чтобы выровнять свой пузырь правильно, вы должны установить 1,0 для layout_constraintHorizontal_bias,

Вот окончательный исходный код:

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

В результате это выглядит так:

Как уже говорилось в других ответах, начиная с ConstraintLayout 1.0 этого можно достичь, но в последней версии (1.1.x) они изменили то, как вы это делаете.

С момента выпуска ConstraintLayout 1.1 старый app:layout_constraintWidth_default="wrap" а также app:layout_constraintHeight_default="wrap" атрибуты теперь устарели.

Если вы хотите предоставить wrap_content поведение, но по-прежнему применять ограничения на ваш вид, вы должны установить его ширину и / или высоту в wrap_content в сочетании с app:layout_constrainedWidth=”true|false” и / или app:layout_constrainedHeight=”true|false” атрибуты, как указано в документах:

WRAP_CONTENT: применение ограничений (добавлено в 1.1) Если для измерения установлено значение WRAP_CONTENT, в версиях до 1.1 они будут обрабатываться как буквальное измерение, то есть ограничения не будут ограничивать результирующее измерение. Хотя в целом этого достаточно (и быстрее), в некоторых ситуациях вы можете захотеть использовать WRAP_CONTENT, но продолжайте применять ограничения для ограничения результирующего измерения. В этом случае вы можете добавить один из соответствующих атрибутов:

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

Что касается последней версии, к тому времени, когда я ответил на это, ConstraintLayout находится на версии 1.1.2.

@nicolas-roard ответ app:layout_constraintWidth_default="wrap" а также android:layout_width="0dp"Теперь DEPRECATED.

Продолжайте и используйте app:layout_constrainedWidth="true" а также android:layout_width="wrap_content".

Причина устаревания, я не знаю. Но это прямо в исходном коде ConstraintLayout

Я использую этот

app:layout_constraintEnd_toEndOf="parent"

Вы должны заменить

android:layout_width="wrap_content"

с

android:layout_width="match_parent"

из вашего TextView, а затем настройте отступы и поля соответственно. Я обновил твой код,

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

Вы получите этот результат

Другие вопросы по тегам