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

132

Я пытаюсь реализовать простой чат, используя расширение 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конкретно спрашиваю ).

Марчин Едынак
источник
вы можете опубликовать текстовое представление вместе с его родительским макетом ограничений? как вы знаете, атрибуты родительского макета имеют большое влияние на ребенка
Мохаммед Атиф
Кстати, в вашем случае я предполагаю, что виноват горизонтальный уклон. попробуйте удалить раскладку справа налево и смещение
Мохаммед Атиф
1
Горизонтальный уклон необходим, иначе пузырек будет по центру. Без компоновки справа налево правое поле не будет учитываться, а это не то, что нам нужно. Я пытался удалить их, как вы советовали, но это не помогло.
Marcin Jedynak
1
Проблема в горизонтальном смещении 0 точно. Я проверю возможные решения и опубликую их как можно скорее, так как я также работаю с чем-то похожим на макет ограничений.
Мохаммед Атиф
1
@nmu пузырь чата исходит от tools:background="@drawable/chat_message_bubble". Чтобы реализовать это, вам нужно создать файл chat_message_bubble.xml в папке с возможностью переноса, а затем добавить этот код: <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FB4382"/> <corners android:radius="10dip"/> </shape>
Евгений Брюсов

Ответы:

242

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

Нет, вы не можете делать то, что хотите, с 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, но будет ограничен ограничениями (т. Е. Не будет расширяться за их пределы)

Обновить. Теперь эти теги устарели, вместо них используйте layout_width = "WRAP_CONTENT" и layout_constrainedWidth = "true".

Николас Роард
источник
1
Для меня это супер проблема. Я не могу использовать TextView с составными чертежами прямо сейчас, потому что, если я установлю его match_constraintsна составные чертежи, они будут справа, даже если есть очень короткий текст.
Пол Войташек
2
@NicolasRoard: вы можете помочь мне с макетом ограничений, у меня есть изображение в верхней половине с ориентиром 0,4 и содержимое ниже, но когда я устанавливаю макет ограничения на wrap_content, он выбирает только 0,4 экрана (и половину текстовые представления ниже не видны), я app:layout_constraintWidth_default="wrap"тоже использовал , и v1.0.2 библиотеки, но это не помогает
Ratatouille
3
app: layout_constraintWidth_default = "wrap" с шириной, поскольку 0dp делает это красиво!
Tunji_D 05
11
это должно быть ЯВНО в документации / инструкциях.
SQLiteNoob
6
Должен ли « Edit» стать более заметным? Вид теряется под оригиналом. Оцените ответ. Спасибо @NicolasRoard.
Том Ховард
277

Обновлено (ConstraintLayout 1.1. +)

Использовать app:layout_constrainedWidth="true"сandroid:layout_width="wrap_content"

Ранее (не рекомендуется):

app:layout_constraintWidth_default="wrap" с участием android:layout_width="0dp"

Сильвия Х
источник
5
Верно, начиная с ConstraintLayout 1.1.0 beta 2, полагаю. androidstudio.googleblog.com/2017/10/…
Fifer Sheep
2
Теперь это в версии 1.1: medium.com/google-developers/…
Эсдрас Лопес,
люблю stackoverflow! спасибо, это помогло мне! сохраните содержимое обертки, но никогда не выходите за рамки ограничений! #TIL
Деннис Андерсон
Какой ответ, не знал, что это существует! Спасибо, чувак, после 2 часов игры с альтернативами это сработало!
dev2505
23

Да, как упоминалось в ответе Николаса Роарда, вы должны добавить 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>

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

введите описание изображения здесь

Евгений Брюсов
источник
Я думаю, это потому, что OP хочет маленький пузырек слева, а ваш - справа, что меняет требования
Waza_Be
2
важная часть здесьapp:layout_constraintHorizontal_bias="1.0"
Лестер
9

Как уже говорилось в других ответах, начиная с 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 .

Mauker
источник
3

Устарело приложение: layout_constraintWidth_default text и его альтернатива

Ответ @nicolas-roard app:layout_constraintWidth_default="wrap"и android:layout_width="0dp"теперь УСТАРЕВШИЙ .

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

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

Bolaji
источник
-7

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

app:layout_constraintEnd_toEndOf="parent"
jsHate
источник
как это ответ на вопрос OP? как это обертывать контент?
Alex
-8

Вам следует заменить

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

Вы получите такой результат введите описание изображения здесь

Mehul
источник
Вам следует избегать использования match_parent для любого представления в ConstraintLayout. Посмотрите «Записку» здесь
Евгений Брюсов