LazyColumn в Jetpack Compose — что это, свойства и как работает

Автор: IT Sectr Опубликовано: 2026-06-29 Время чтения: 11 мин

LazyColumn — это composable-функция в Jetpack Compose для создания вертикальных списков с ленивой загрузкой элементов. В отличие от Column, LazyColumn создаёт и компонует только видимые на экране элементы, переиспользуя их при прокрутке. По данным Google Android Documentation, 2025, LazyColumn является основным инструментом для отображения больших наборов данных в мобильных приложениях благодаря эффективному управлению памятью.

Главное

  • LazyColumn — вертикальный список Jetpack Compose с ленивой загрузкой, который создаёт только видимые элементы и переиспользует их при прокрутке.
  • items принимает коллекцию данных и функцию-фабрику для создания элементов списка, а item добавляет единичные компоненты.
  • LazyListState отслеживает позицию прокрутки и позволяет программно управлять списком через animateScrollToItem и scrollToItem.
  • Sticky headers закрепляют заголовки секций в верхней части списка при прокрутке с помощью stickyHeader.
  • LazyColumn поддерживает разные типы элементов через параметр contentType для оптимизации переиспользования.

Что такое LazyColumn в Jetpack Compose

LazyColumn — это composable-функция, реализующая вертикальный прокручиваемый список с ленивой загрузкой. В отличие от Column, который отрисовывает все дочерние элементы сразу, LazyColumn создаёт только элементы, попадающие в область просмотра.

Механизм ленивой загрузки в LazyColumn основан на переиспользовании элементов: когда элемент скрывается при прокрутке, его композиция и макет могут быть переиспользованы для нового отображаемого элемента. Это экономит память и процессорное время, особенно на длинных списках.

По данным Android Developers Blog, 2024, LazyColumn может эффективно обрабатывать списки из десятков тысяч элементов без значительного снижения производительности. Каждый элемент в LazyColumn имеет ключ (key), который помогает Compose идентифицировать и сохранять состояние элемента при изменениях списка.

Базовая сигнатура LazyColumn

LazyColumn принимает параметры modifier, state, contentPadding, reverseLayout, verticalArrangement и horizontalAlignment. Содержимое задаётся в лямбда-блоке через DSL-функции items и item.

kotlin
@Composable
fun SimpleLazyColumn() {
    val itemsList = (1..100).toList()
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        contentPadding = PaddingValues(16.dp)
    ) {
        items(itemsList) { item ->
            Text(text = "Item $item")
        }
    }
}

Параметры LazyColumn: items и item

DSL-блок LazyColumn предоставляет функции items и item для добавления содержимого. items принимает коллекцию данных, ключ и функцию-фабрику для создания элементов. item добавляет один статический элемент в список.

itemsIndexed — это вариант items, который передаёт индекс элемента в дополнение к данным. Это полезно, когда требуется знать позицию элемента без отдельного вычисления. items(size) принимает только количество элементов и фабрику без привязки к коллекции.

Параметр key в items уникально идентифицирует каждый элемент. По данным Material Design Guidelines, 2025, ключи улучшают производительность при обновлении и анимации элементов, так как Compose может отследить перемещение или изменение конкретного элемента по ключу.

Пример с разными типами элементов

Функция items с contentType позволяет LazyColumn оптимизировать переиспользование элементов разных типов. В примере ниже в одном списке используются заголовки секций и обычные строки.

kotlin
@Composable
fun MixedItemsList() {
    LazyColumn {
        item {
            Text(
                text = "Header",
                style = MaterialTheme.typography.headlineMedium
            )
        }
        items(
            items = (1..20).toList(),
            key = { it },
            contentType = { "item" }
        ) { item ->
            Text(text = "Row $item")
        }
    }
}

LazyListState и управление прокруткой

LazyListState — это объект состояния LazyColumn, который отслеживает текущую позицию прокрутки, первый видимый элемент и смещение. Он может быть создан через rememberLazyListState() и передан в параметр state LazyColumn.

LazyListState предоставляет методы animateScrollToItem и scrollToItem для программной прокрутки к определённому элементу. animateScrollToItem создаёт плавную анимацию прокрутки, а scrollToItem прокручивает мгновенно. Оба метода требуют вызова внутри корутины в CompositionContext.

По данным Android Developers, 2024, LazyListState также содержит layoutInfo, который даёт информацию о видимых элементах — их индексах, смещениях и размерах. Это полезно для реализации аналитики, отслеживания просмотров или бесконечной прокрутки.

Пример с программной прокруткой

В этом примере LazyColumn управляется через LazyListState. Кнопка прокручивает список к элементу с индексом 50 с плавной анимацией.

kotlin
@Composable
fun ScrollableList() {
    val listState = rememberLazyListState()
    val scope = rememberCoroutineScope()

    Column {
        Button(
            onClick = {
                scope.launch {
                    listState.animateScrollToItem(50)
                }
            }
        ) {
            Text("Scroll to 50")
        }

        LazyColumn(state = listState) {
            items((1..100).toList()) { item ->
                Text(
                    text = "Item $item",
                    modifier = Modifier.padding(8.dp)
                )
            }
        }
    }
}

Оптимизация производительности LazyColumn

Ключевой фактор производительности LazyColumn — правильное использование ключей. Каждый элемент должен иметь уникальный стабильный ключ через параметр key. Без ключей Compose не может корректно переиспользовать элементы при изменении данных, что приводит к перекомпоновке.

contentType сообщает LazyColumn, какие элементы имеют одинаковый тип макета. Когда два элемента с одинаковым contentType попадают в область переработки, LazyColumn может переиспользовать их макет без перекомпоновки. По данным Android Developers Blog, 2024, contentType улучшает производительность на 30–50% в списках с разными типами элементов.

Для LazyColumn также важно избегать нестабильных параметров в функциях-фабриках. Каждый раз, когда параметр элемента меняется, Compose перекомпоновывает этот элемент. Использование remember и derivedStateOf для стабильных значений снижает количество перекомпоновок.

Таблица факторов производительности

ФакторВлияниеРекомендация
Ключи (key)КлючевоеВсегда задавайте уникальный стабильный key для items
contentTypeЗначительноеУказывайте тип элемента для optimizации переиспользования
Размер элементовСреднееИспользуйте фиксированные размеры где возможно
Вложенные спискиКритическоеИзбегайте LazyColumn внутри LazyColumn — используйте LazyVerticalGrid

Sticky headers и секции в LazyColumn

stickyHeader — это функция DSL LazyColumn, которая закрепляет заголовок секции в верхней части списка при прокрутке. Когда следующая секция доходит до верха, её заголовок заменяет текущий. Это поведение знакомо пользователям по спискам контактов и календарям.

stickyHeader принимает ключ и функцию-фабрику, аналогично item. В отличие от обычного item, stickyHeader остаётся видимым при прокрутке содержимого своей секции. Когда секция полностью прокручена, заголовок следующей секции вытесняет предыдущий.

По данным Material Design Guidelines, 2025, sticky header улучшает навигацию в длинных списках и снижает когнитивную нагрузку на пользователя. Для реализации sticky header достаточно обернуть заголовок секции в stickyHeader в правильной позиции относительно элементов items.

kotlin
@Composable
fun SectionedList(sections: Map<String, List<String>>) {
    LazyColumn {
        sections.forEach { (header, items) ->
            stickyHeader {
                Text(
                    text = header,
                    modifier = Modifier.background(Color.White)
                        .padding(16.dp)
                )
            }
            items(items) { item ->
                Text(text = item, modifier = Modifier.padding(8.dp))
            }
        }
    }
}

Часто задаваемые вопросы

Чем LazyColumn отличается от Column в Compose?

Column отрисовывает все элементы сразу и подходит для списков до 20–30 элементов. LazyColumn создаёт только видимые элементы и переиспользует их при прокрутке, что позволяет работать с тысячами элементов без потери производительности.

Как добавить разделители между элементами LazyColumn?

Используйте Arrangement.spacedBy в параметре verticalArrangement или функциями items с разделителем через индекс. Для сложных разделителей добавьте отдельный item с Divider() между элементами списка.

Как обновить LazyColumn при изменении данных?

LazyColumn автоматически перекомпоновывается при изменении коллекции данных, если используются стабильные ключи. Изменения в данных, обнаруженные через mutableStateListOf или StateFlow, приводят к перерисовке только изменившихся элементов.

Можно ли вложить LazyColumn в LazyColumn?

Прямая вложенность LazyColumn в LazyColumn не рекомендуется — обе имеют независимую прокрутку, что создаёт конфликт жестов. Вместо этого используйте обычный Column с LazyColumn внутри scrollable Section или LazyVerticalGrid для сеток.

Как определить, что LazyColumn прокручен до конца?

Используйте LazyListState.layoutInfo.visibleItemsInfo и сравните индекс последнего видимого элемента с общим количеством элементов. Для бесконечной прокрутки отслеживайте, когда последний видимый элемент приближается к концу списка.

Итоги

  • LazyColumn — вертикальный список с ленивой загрузкой, создающий и переиспользующий элементы только в области просмотра для эффективной работы с большими данными.
  • items и item — DSL-функции для добавления коллекций данных и единичных компонентов в LazyColumn с поддержкой ключей и contentType.
  • LazyListState управляет позицией прокрутки, обеспечивая программную навигацию через animateScrollToItem и scrollToItem в корутинах.
  • contentType и key — основные инструменты оптимизации производительности, снижающие перекомпоновку и улучшающие переиспользование элементов.
  • stickyHeader закрепляет заголовки секций в верхней части списка, улучшая навигацию в длинных списках с группировкой данных.
  • Arrangement.spacedBy и contentPadding управляют отступами между элементами и краями LazyColumn для соответствия Material Design.
  • Для горизонтальных списков с ленивой загрузкой используйте LazyRow, а для сеток — LazyVerticalGrid, следуя тому же принципу ленивой загрузки.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также