Иметь представление обтекания содержимого, но соответствовать родительскому, если есть свободное место - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть два представления в пределах LinearLayout, оба из которых должны wrap_content, чтобы они были минимально достаточно большими, чтобы отображать их содержимое.LinearLayout группа представлений должна wrap_content из двух дочерних групп, чтобы она была достаточно большой для отображения содержимого обоих дочерних представлений.

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

Два дочерних представления - это TextView и Spinner.Spinner должен заполнить все оставшееся пространство шириной LinearLayout.Но если я изменю Spinner layout_width на match_parent, а TextView будет недостаточно большим, Spinner будет обрезать его содержимое.

В основном мне нужен способ выбрать максимальную ширинумежду wrap_content и match_parent.

Это макет:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="-2dp"
        android:layout_marginBottom="-2dp"
        android:paddingStart="4dp"
        android:paddingEnd="4dp"
        android:textSize="12sp"
        android:textColor="?android:textColorHint"
        tools:text="Label" />

    <Spinner
        android:id="@+id/spinner"
        style="@style/Widget.AppCompat.Spinner.Underlined"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
<!-- or android:layout_width="match_parent"? need max of both... -->

</LinearLayout>

Ответы [ 5 ]

0 голосов
/ 02 января 2019

Для достижения этой цели можно использовать LinearLayout без дополнительных представлений: используйте wrap_content для родительского LinearLayout и match_parent для обоих дочерних элементов.Пока у LinearLayout нет любых дочерних элементов с фиксированными размерами, эта комбинация сделает общий родительский элемент столь же широким, как и его самый широкий дочерний элемент.

<LinearLayout
    android:layout_width="wrap_content"
    ...>

    <TextView
        android:layout_width="match_parent"
        .../>

    <Spinner
        android:layout_width="match_parent"
        .../>

</LinearLayout>

enter image description here

enter image description here

(я добавил цвет фона для LinearLayout, чтобы было легче увидеть, как он сам изменяет размеры.)

0 голосов
/ 02 января 2019

Обновление: Ответ Бен П завершает это, все еще используя LinearLayout.

После дальнейшего тестирования различных решений оказывается, что лучшим решением является не использовать LinearLayout в качестверодительская группа просмотра.По какой-либо причине FrameLayout обеспечивает желаемое поведение переноса содержимого дочернего представления, даже когда дочернее представление установлено на match_parent, так что используется максимум двух размеров.LinearLayout не обеспечивает такое же поведение.

Но тогда проблема в том, как заставить два дочерних представления располагаться вертикально.Это может быть достигнуто в FrameLayout с помощью комбинации layout_gravity и Space.По какой-то странной причине, по крайней мере, в моем случае использования этого макета в качестве элемента в родительском элементе FlexboxLayout, установка высоты FrameLayout явно не подойдет для измерения его высоты.Использование wrap_content с представлением Space, установленным на требуемую высоту, действительно работает.

Это макет, который работает, не требуя дополнительного кода:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <!-- setting FrameLayout layout_height doesn't work for some reason -->
    <Space
        android:layout_width="0dp"
        android:layout_height="56dp" />

    <TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="top|start"
    android:layout_marginTop="-2dp"
    android:layout_marginBottom="-2dp"
    android:paddingStart="4dp"
    android:paddingEnd="4dp"
    android:textSize="12sp"
    android:textColor="?android:textColorHint"
    tools:text="Label" />

    <Spinner
        android:id="@+id/spinner"
        style="@style/Widget.AppCompat.Spinner.Underlined"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" />

</FrameLayout>
0 голосов
/ 30 декабря 2018

попробуйте установить вес макета android:layout_weight.вот определение из SO: https://stackoverflow.com/a/3996104/8738574.установите вес счетчика так, чтобы он был больше, чем у textView, а ширина - 0 (ноль).

TextView:

android:layout_weight="1"
android:layout_width="0px"

Spinner:

android:layout_weight="2"
android:layout_width="0px"
0 голосов
/ 31 декабря 2018

Обновление: см. Другой мой ответ для лучшего решения.

Хотелось бы, чтобы было более элегантное решение, но я достиг этого путем добавления дополнительного скрытого дубликата.Spinner представление используется только для определения размера родительского элемента LinearLayout для достижения максимального значения wrap_content или match_parent, в зависимости от того, что больше.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="-2dp"
        android:layout_marginBottom="-2dp"
        android:paddingStart="4dp"
        android:paddingEnd="4dp"
        android:textSize="12sp"
        android:textColor="?android:textColorHint"
        tools:text="Label" />

    <Spinner
        android:id="@+id/spinner"
        style="@style/Widget.AppCompat.Spinner.Underlined"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <!-- visible view width set to match_parent -->

    <Spinner
        android:id="@+id/spinnerHiddenSizer"
        style="@style/Widget.AppCompat.Spinner.Underlined"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:visibility="invisible" />
    <!-- invisible view width set to wrap_content -->
    <!-- also set height to 0dp so it takes up no vertical space -->
    <!-- in code, set this Spinner's adapter to the same as -->
    <!-- the visible spinner so that it's sized the same -->

</LinearLayout>

Таким образом, если wrap_content будетиз-за того, что ширина Spinner будет больше match_parent, скрытый вид увеличит размер LinearLayout до этого большего размера, а видимая ширина match_parent увеличится до этой ширины.

0 голосов
/ 30 декабря 2018

Проблема в том, что ваша LinearLayout ширина равна wrap_content.Это означает, что дети никогда не будут заполнять всю ширину, только если содержимое внутри изменит ширину.

Просто измените строку внутри LinearLayout.От:

android:layout_width="wrap_content"

До

android:layout_width="match_parent"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...