Connect with us

Разработка

Flow-контейнеры в Compose

Понимая и используя эти функции, вы сможете создавать более адаптивные и визуально привлекательные пользовательские интерфейсы в Jetpack Compose.

Опубликовано

/

     
     

В мире разработки UI ключевая задача — создание отзывчивого и адаптивного пользовательского интерфейса. Jetpack Compose, современный набор инструментов для создания UI в Android, предлагает широкий выбор composables для верстки, которые помогают разработчикам создавать динамичные и гибкие интерфейсы. И хотя стандартные контейнеры, такие как Row и Column, отлично подходят для линейного расположения элементов, они не всегда справляются с контентом, который должен адаптироваться и переноситься в зависимости от доступного пространства. Именно здесь на помощь приходят flow-контейнеры (контейнеры с потоковым расположением).

FlowRow и FlowColumn — это composables, похожие на Row и Column, но с одним ключевым отличием: элементы автоматически переносятся на следующую строку, когда в контейнере заканчивается место. Такое поведение создает несколько строк или столбцов, позволяя создавать более адаптивные интерфейсы, в которых контент не обрезается, если элементы слишком велики для одного измерения. Они особенно полезны для создания таких элементов интерфейса, как набор «чипов» или фильтров, где элементы должны переноситься на следующую строку по мере уменьшения пространства на экране.

В этой статье мы подробно рассмотрим возможности flow-контейнеров, узнаем, как управлять расположением элементов, выравнивать их по отдельности и использовать «веса» (weights) для создания адаптивных сеточных структур.

Выбор между «ленивыми» (lazy) и «потоковыми» (flow) контейнерами

При выборе между lazy-контейнером (LazyRow/LazyColumn) и flow-контейнером (FlowRow/FlowColumn) ключевыми факторами являются количество отображаемых элементов и желаемое поведение.

Lazy-контейнеры — это оптимальный выбор для отображения больших или потенциально бесконечных списков, требующих прокрутки. Эти контейнеры высокопроизводительны, поскольку они компонуют (отрисовывают) только те элементы, которые в данный момент видны на экране — этот подход известен как «ленивая загрузка» (lazy loading). Он идеален для списков или сеток с вертикальной (LazyColumn) или горизонтальной (LazyRow) прокруткой, так как экономит память и предотвращает проблемы с производительностью, которые возникли бы при одновременной отрисовке всех элементов.

Flow-контейнеры, с другой стороны, лучше всего подходят для небольшого, фиксированного количества элементов, когда требуется, чтобы они автоматически переносились на следующую строку или в следующий столбец при заполнении пространства контейнера. В отличие от lazy-контейнеров, flow-контейнеры компонуют все дочерние элементы сразу. Они не предназначены для прокрутки, а скорее для создания компоновок с переносом, где элементы естественным образом «перетекают» на следующую строку в ограниченном пространстве.

Для более детального изучения lazy-контейнеров вы можете обратиться к официальной документации Android. Если вам нужны возможности как lazy, так и flow контейнеров, рассмотрите использование «ленивых сеток» (lazy grids). Больше информации о lazy grids вы можете найти в моей статье.

Базовое использование

Чтобы использовать FlowRow или FlowColumn, просто создайте компонуемый объект и разместите в нём элементы. Элементы будут следовать стандартным правилам компоновки потока, автоматически переносясь на новую строку при необходимости. Типичный пример — интерфейс чипов.

@Composable
fun FlowRowSimpleUsageExample() {
    FlowRow(modifier = Modifier.padding(8.dp)) {
        ChipItem("Price: High to Low")
        ChipItem("Avg rating: 4+")
        ChipItem("Free breakfast")
        ChipItem("Free cancellation")
        ChipItem("£50 pn")
    }
}

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

Обработка элементов разного размера и веса

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

@Composable
fun FlowRowVaryingSizesExample() {
    FlowRow(
        modifier = Modifier
            .fillMaxWidth()
            .padding(12.dp),
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        val itemWeights = listOf(1f, 2f, 1.5f, 1f, 2.5f, 1.2f, 1.8f, 1.3f)
        repeat(8) { i ->
            Text(
                text = "Item ${i + 1}",
                modifier = Modifier
                    .height(48.dp)
                    .weight(itemWeights[i % itemWeights.size])
                    .clip(RoundedCornerShape(16.dp))
                    .background(Color.Blue)
                    .padding(8.dp),
                color = Color.White
            )
        }
    }
}

Кроме того, важной особенностью flow макетов является использование весов элементов. Это позволяет элементам увеличиваться в зависимости от заданного коэффициента и доступного пространства в их строке. Важно понимать, что в FlowRow вес рассчитывается только на основе других элементов в той же строке, в отличие от обычной Row, где он рассчитывается на основе всех элементов в Row.

Например, если строка в FlowRow содержит два элемента с весами 0.5f и 0.5f, каждый из них займет половину доступной ширины этой строки. Если в строке есть один элемент с Modifier.fillMaxWidth(), он займет всю ширину строки.

Вы можете объединить Modifier.weight с maxItemsInEach, чтобы создать адаптивный макет, похожий на сетку, который адаптируется к размеру устройства, как показано ниже. Это полезно для создания макетов с чередующимися размерами элементов.

@Composable
fun FlowRowWeighted(modifier: Modifier = Modifier) {
    FlowRow(
        modifier = Modifier.padding(4.dp),
        horizontalArrangement = Arrangement.spacedBy(4.dp),
        maxItemsInEachRow = 2
    ) {
        val itemModifier = Modifier
            .padding(4.dp)
            .height(80.dp)
            .clip(RoundedCornerShape(8.dp))
            .background(Color.Blue)
        repeat (6) { item ->
            if ((item + 1) % 3 == 0) {
                Spacer(modifier = itemModifier.fillMaxWidth())
            } else {
                Spacer(modifier = itemModifier.weight(0.5f))
            }
        }
    }
}

За пределами основ: тонкая настройка Flow макетов

Макеты Flow в Jetpack Compose выходят далеко за рамки простого размещения элементов рядом друг с другом. С помощью нескольких дополнительных параметров вы можете точно контролировать отступы, выравнивание и компоновку вашего пользовательского интерфейса.

Главная ось — это направление естественного расположения элементов: горизонтальное в FlowRow и вертикальное в FlowColumn. Вдоль этой оси вы можете настроить распределение пространства между элементами с помощью horizontalArrangement (для FlowRow) или verticalArrangement (для FlowColumn). Хотите ли вы, чтобы всё было расположено ближе к началу, сдвинуто в конец, по центру, равномерно распределено или разделено фиксированным зазором, эти настройки дают вам необходимый контроль.

Поперечная ось — это перпендикулярное направление: вертикальное в FlowRow и горизонтальное в FlowColumn. Она управляет тем, как все строки или столбцы располагаются внутри контейнера. По умолчанию элементы располагаются сверху в FlowRow и в начале в FlowColumn, но вы можете изменить это в соответствии с вашим макетом.

Если один элемент должен выделяться или нарушать правила выравнивания, Modifier.align() позволяет расположить его иначе, чем соседние. Это особенно полезно, когда элементы различаются по высоте или ширине, или когда вы хотите, чтобы один элемент визуально выделялся.

Наконец, вы можете контролировать количество элементов, отображаемых в одной строке или столбце, с помощью maxItemsInEachRow или maxItemsInEachColumn. Значение по умолчанию фактически не ограничено, но установка значения, например, 3, мгновенно создаст аккуратный вид сетки. Комбинируя эти настройки, вы можете перейти от простого потока элементов к продуманному, точно организованному интерфейсу без написания большого количества кода.

Резюме

Эта статья представляет собой подробное руководство по использованию потоковых макетов в Jetpack Compose. Flow макеты — важнейший инструмент для создания адаптивных пользовательских интерфейсов, подстраивающихся к различным размерам экранов благодаря возможности переноса контента на новые строки. Мы рассмотрели ключевые различия между потоковыми макетами и ленивыми макетами, продемонстрировав, что потоковые макеты лучше подходят для небольших интерфейсов с фиксированным количеством элементов, где перенос элементов предпочтительнее прокрутки.

Мы также рассмотрели основные функции потоковых макетов, включая:

  • Основы использования на примере чипового пользовательского интерфейса, адаптирующегося к различным размерам экранов.
  • Использование веса элементов для создания динамичных и адаптивных структур, подобных сетке.
  • Расширенные параметры для управления расположением, выравниванием и максимальным количеством элементов в строке, обеспечивающие детальный контроль над макетами.

Понимая и используя эти функции, вы сможете создавать более адаптивные и визуально привлекательные пользовательские интерфейсы в Jetpack Compose.

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: