Плоский ConstraintLayout с layout_constraintHeight_min для каждой строки не работает

У меня есть то, что я считаю довольно распространенным вариантом использования: у меня есть несколько строк информации на экране. Я надеюсь реализовать эти представления без использования вложенных групп просмотра. Каждая строка должна иметь минимальную высоту, но расширяться, если ее содержимое превышает минимальную высоту. Содержимое должно быть вложено вертикально.

Похоже, что этот упрощенный пример должен работать:

<?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"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">

    <TextView
        android:id = "@+id/textView"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "Row"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent"
        app:layout_constraintTop_toTopOf = "@+id/view"
        app:layout_constraintBottom_toBottomOf = "@+id/view"/>

    <View
        android:id = "@+id/view"
        android:layout_width = "match_parent"
        android:layout_height = "0dp"
        android:background = "#8800ff00"
        app:layout_constraintHeight_min = "100dp"
        app:layout_constraintTop_toTopOf = "parent"
        app:layout_constraintBottom_toBottomOf = "@id/textView"/>

</android.support.constraint.ConstraintLayout>

Вместо создания ViewGroup для каждой строки у меня есть плоский макет с ограничениями. Представление для каждой строки устанавливает высоту строки и может быть интерактивным. Представления внутри строки являются одноуровневыми в иерархии макета, но центрируют себя вертикально в середине представления для этой строки. Поскольку я указал app:layout_constraintHeight_min и привязал нижнюю часть представления к нижней части содержимого, он должен расти вместе с содержимым.

Но есть проблема:

Плоский ConstraintLayout с layout_constraintHeight_min для каждой строки не работает

ConstraintLayout добавляет нежелательный интервал над строкой! Обратите внимание, что нежелательный интервал над строкой равен правильному интервалу между нижней частью содержимого и нижней частью строки.

Моя теория такова: поскольку нижняя часть представления привязана к нижней части содержимого (TextView), он хочет плотно прилипнуть к нему и быть прямо рядом с ним. Если я заставлю его отодвинуться еще дальше, он добавит что-то вроде нижнего поля для этого, он добавит аналогичное верхнее поле, чтобы оно было симметричным.

Как мне это остановить? Если бы не этот нежелательный промежуток сверху, у меня было бы именно то, что мне нужно. Возможно, есть какой-то особый трюк с ConstraintLayout, какой-то волшебный атрибут, чтобы исправить это поведение. Или, может быть, есть совершенно другой способ использования ConstraintLayout для реализации нужного мне пользовательского интерфейса.

Я понимаю, что использование строк с фиксированной высотой значительно упростит это, но мне не нравится делать это, если содержимое может увеличиваться.

Я мог бы изменить свой пользовательский интерфейс, чтобы иметь вложенный ConstraintLayout для каждой строки, но я бы предпочел не делать этого после стольких усилий, чтобы сделать сложный макет полностью плоским, без нескольких слоев ViewGroups. Но это то, что я сделаю, если не смогу найти лучшее решение, которое я надеюсь найти здесь.

Итак, в основном вам нужно "wrap_content" с min_height.

TheLibrarian 29.11.2018 07:49

Нижняя часть текстового представления ограничена нижней частью зеленого представления, но нижняя часть зеленого представления ограничена нижней частью текстового представления. Это циклическая зависимость, которая неудачно разрешается, а не вызывает ошибку. Похоже, вы хотите, чтобы зеленое представление выглядело как группа представлений. Без зеленого представления все виджеты размещены правильно, а зеленый вид - это просто оболочка, или виджеты зависят от размещения зеленого представления? Ответ на этот вопрос приведет к ответу.

Cheticamp 29.11.2018 14:15

@TheLibrarianCz эквивалент этого ConstraintLayout, да. Но для использования wrap_content потребуются дополнительные ViewGroups, которых я стараюсь избегать. Я пробовал экспериментировать с layout_constraintHeight_default = wrap, но не нашел способа заставить его делать то, что я хочу. Если у вас есть решение, я был бы признателен.

Chad Schultz 29.11.2018 15:58

@Cheticamp То, что я предоставил, является минимальной демонстрацией проблемы. Да, зеленый вид необходим. Да, он действует как ViewGroup, но не является ViewGroup. Зеленый вид помогает управлять высотой строки и делать всю область строки интерактивной. Если есть другой способ достичь перечисленных мною целей, я открыт для предложений.

Chad Schultz 29.11.2018 15:59

После экспериментов и исследований я не могу найти ответа на этот вопрос. Я сдаюсь и, к сожалению, переделываю свой идеально плоский макет так, чтобы он имел вложенный ConstraintLayout для каждой строки. Возможно, будущий выпуск ConstraintLayout будет обрабатывать этот типичный вариант использования.

Chad Schultz 04.12.2018 17:31
0
5
1 091
1

Ответы 1

Я думаю, что удаление минимальной высоты и добавление некоторого поля в TextView сделает это, и вместо использования match_parent вы можете использовать ограничения, если это возможно

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.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/textView"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_margin = "50dp"
        android:text = "Row is not column"
        android:textColor = "#283858"
        app:layout_constraintBottom_toBottomOf = "@+id/view"
        app:layout_constraintEnd_toEndOf = "parent"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "@+id/view"/>

    <View
        android:id = "@+id/view"
        android:layout_width = "0dp"
        android:layout_height = "0dp"
        android:background = "#8800ff00"
        app:layout_constraintBottom_toBottomOf = "@id/textView"
        app:layout_constraintEnd_toEndOf = "parent"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Here is my output

Спасибо за ответ! проблема в том, что в этом случае мне нужно точно установить минимальную высоту - мой реальный вариант использования более сложен, чем этот пример.

Chad Schultz 29.11.2018 15:56

поэтому я думаю, что это занимает некоторую минимальную высоту, даже если нет содержимого

Abraham Mathew 30.11.2018 04:14

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