Списки LazyColumn и LazyRow

Последнее обновление: 03.04.2024

Если необходимо отобразить большое количество элементов (или список неизвестной длины), использование стандартных контейнеров как Column или Row может вызвать проблемы с производительностью, так как все вложенные элементы будут скомпонованы внутри контейнера независимо от того, видимы они или нет. Для более эффективной работы со вложенными компонентами Jetpack Compose предоставляет такие компоненты-контейнеры как LazyColumn и LazyRow. Они компонуют и добавляют только те элементы, которые видны в окне просмотра компонента. При прокрутке в контейнер компонуются новые элементы, а старые удаляются. При обратной прокрутке происходит повторная компоновка старых элементов. Собственно название контейнеров уже говорит о том, что они производят так называюмую lazy-загрузку (или ленивую загрузку), когда элементы загружаются не сразу, а по мере необходимости.

LazyColumn

LazyColumn создает список с вертикальной прокруткой, а LazyRow создает список с горизонтальной прокруткой и имеет следующие параметры:

@Composable
fun LazyColumn(
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyListScope.() -> Unit
): Unit
  • modifier: применяемые к контейнеру модификаторы

  • state: объект состояния LazyListState, применяемый для управления состоянием контейнера

  • contentPadding: отступы вокруг содержимого

  • reverseLayout: при значении true располагает элементы в обратном порядке

  • verticalArrangement: настройки расположения элементов по вертикали

  • horizontalAlignment: выравнивание элементов по горизонтали

  • flingBehavior: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец. Представляет объект FlingBehavior

  • userScrollEnabled: указывает, доступна ли прокрутка жестами либо через специальные инструменты управления доступом

  • content: устанавливает содержимое контейнера с помощью функции типа LazyListScope.() -> Unit.

Одно из отличий lazy-контейнеров, в частности, LazyColumn от других контейнеров, например, от Column состоит в принципе установки содержимого. За это отвечает функция типа LazyListScope.() -> Unit. Внутри блока этой функции можно использовать специальные методы для добавления других компонентов:

  • LazyListScope.item(): для добавления одного элемента

  • LazyListScope.items(): для добавления нескольких элементов

  • LazyListScope.itemsIndexed(): для добавления нескольких элементов с использованием индексов

Например, применение функции LazyListScope.item() для добавление в LazyColumn одного элемента:

LazyColumn( Modifier.fillMaxSize()){
    item { Text("Hello METANIT.COM", fontSize = 28.sp) }
}

В данном случае добавляется компонент Text.

Функция LazyListScope.items() принимает список значений для каждого из которых создается элемент в LazyColumn:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text

import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf("Kotlin", "Java", "JavaScript", "Python", "C#", "C++", "Rust")
            LazyColumn(
                Modifier.fillMaxSize()
            ){
                items(langs){lang -> Text(lang, fontSize = 24.sp)}
            }
        }
    }
}

Здесь для создания содержимого в LazyColumn применяется список langs. Функция items принимает этот список в качестве параметра и для каждого его элемента вызывает функцию @Composable() (LazyItemScope.(item: T) -> Unit). Здесь в качестве такой функции выступает функция {lang -> Text(lang, fontSize = 24.sp)}, которая для каждого элемента списка создает компонент Text

LazyColumn в Jetpack Compose и Kotlin на Android

Причем для создания элементов можно сочетать сразу несколько функций item()/items():

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf("Kotlin", "Java", "JavaScript", "Python", "C#", "C++", "Rust")
            LazyColumn(
                Modifier.fillMaxSize()
            ){
                item { Text("Языки программирования", fontSize = 29.sp) }
                items(langs){lang -> Text(lang, fontSize = 24.sp)}
            }
        }
    }
}
Добавление элементов в LazyColumn в Jetpack Compose и Kotlin на Android

Еще одна функция itemsIndexed() аналогично items() принимает список/массив элементов, но при переборе позволяет получить их индекс. Например, применим индекс для определения фонового цвета компонента:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf("Kotlin", "Java", "JavaScript", "Python", "C#", "C++", "Rust")
            LazyColumn(
                modifier = Modifier.fillMaxSize(),
                contentPadding = PaddingValues(5.dp)
            ){
                item { Text("Языки программирования", fontSize = 29.sp) }
                itemsIndexed(langs){index,lang -> Text(lang, fontSize = 23.sp,
                    modifier=Modifier.background(
                        if(index%2==0) Color(0xffdddddd) else Color.Transparent
                    ).padding(8.dp).fillMaxWidth())}
            }
        }
    }
}
Настройка элементов в LazyColumn в Jetpack Compose и Kotlin на Android

LazyRow

Контейнер LazyRow создает список с горизонтальной прокруткой. Он имеет следующие параметры:

@Composable
fun LazyRow(
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyListScope.() -> Unit
): Unit
  • modifier: применяемые к контейнеру модификаторы

  • state: объект состояния LazyListState, применяемый для управления состоянием контейнера

  • contentPadding: отступы вокруг содержимого

  • reverseLayout: при значении true располагает элементы в обратном порядке

  • horizontalArrangement: настройки расположения элементов по горизонтали

  • verticalAlignment: выравнивание элементов по вертикали

  • flingBehavior: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец. Представляет объект FlingBehavior

  • userScrollEnabled: указывает, доступна ли прокрутка жестами либо через специальные инструменты управления доступом

  • content: устанавливает содержимое контейнера с помощью функции типа LazyListScope.() -> Unit.

В целом LazyRow похож на LazyColumn, таким же образом устанавливает элементы, только располагает их по горизонтали. Например, простейший горизонтальный список:

val langs = listOf("Kotlin", "Java", "JavaScript", "Python")
LazyRow {
    items(langs) {lang -> Text(lang)}
}

Также это может быть более сложное содержимое:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf(Language("Kotlin", 0xff16a085),
                Language("Java", 0xff2980b9),
                Language("JavaScript", 0xffd35400),
                Language("Python", 0xff2c3e50))
            LazyRow{
                items(langs) {lang ->
                    Column(Modifier.padding(8.dp), horizontalAlignment = Alignment.CenterHorizontally){
                        Box(Modifier.size(100.dp).background(Color(lang.hexColor)))
                        Text(lang.name, fontSize = 24.sp,modifier= Modifier.padding(8.dp))
                    }
                }
            }
        }
    }
}

data class Language(val name:String, val hexColor: Long)
Настройка элементов в LazyRow в Jetpack Compose и Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850