LazyRow — це функція-компонований елемент у Jetpack Compose для створення горизонтальних списків з лінивим завантаженням елементів. На відміну від Row, LazyRow створює лише видимі елементи та перевикористовує їх під час горизонтальної прокрутки. Згідно з Google Android Documentation, 2025, LazyRow є горизонтальним аналогом LazyColumn та ефективний для каруселей, галерей і горизонтальних меню в мобільних додатках.
Головне
LazyRow — це функція-компонований елемент, що реалізує горизонтальний прокручуваний список з лінивим завантаженням елементів. На відміну від Row, який рендерить всі дочірні елементи одночасно, LazyRow створює лише елементи, видимі в області перегляду.
LazyRow працює за тим же принципом, що й LazyColumn, але розташовує елементи горизонтально. Під час прокрутки вліво або вправо елементи, що вийшли з області перегляду, перевикористовуються для відображення нових. Це критично важливо для галерей з великою кількістю зображень або довгих списків категорій.
Згідно з Android Developers Blog, 2024, LazyRow використовує ту ж архітектуру LazyList, що й LazyColumn, включаючи LazyListState, механізм перевикористання через Pool та підтримку різних типів елементів. Максимальна ефективність досягається при фіксованій висоті елементів.
LazyRow приймає параметри modifier, state, contentPadding, reverseLayout, horizontalArrangement та verticalAlignment. Вміст задається через DSL-функції items та item, аналогічно LazyColumn.
@Composable
fun SimpleLazyRow() {
val items = (1..50).toList()
LazyRow(
modifier = Modifier.fillMaxWidth().height(100.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(start = 16.dp, end = 16.dp)
) {
items(items) { item ->
Box(
modifier = Modifier.size(80.dp).background(Color.Gray)
) {
Text(text = "$item", modifier = Modifier.align(Alignment.Center))
}
}
}
}
horizontalArrangement керує розподілом елементів по горизонтальній осі всередині LazyRow. Доступні ті самі значення Arrangement, що й у Row: Start, Center, End, SpaceBetween, SpaceEvenly, SpaceAround та spacedBy з кастомним відступом.
contentPadding додає відступи по краях контейнера LazyRow. На відміну від Modifier.padding, contentPadding враховується під час прокрутки: перший елемент матиме відступ від лівого краю, останній — від правого. Згідно з Material Design Guidelines, 2025, contentPadding обов'язковий для каруселей і галерей, щоб перший та останній елементи не прилипали до краю екрана.
verticalAlignment вирівнює елементи по вертикалі всередині LazyRow. За замовчуванням використовується Alignment.Top. Для центрування елементів різної висоти використовуйте Alignment.CenterVertically, що корисно для каруселей із зображеннями різних пропорцій.
| Параметр | Опис | Значення за замовчуванням |
|---|---|---|
| horizontalArrangement | Розподіл елементів по горизонталі | Arrangement.Start |
| contentPadding | Відступи по краях контейнера | PaddingValues(0.dp) |
| verticalAlignment | Вирівнювання по вертикалі | Alignment.Top |
| reverseLayout | Зворотний порядок елементів | false |
| userScrollEnabled | Дозвіл прокрутки користувачем | true |
LazyListState для LazyRow працює ідентично LazyColumn: він відстежує перший видимий елемент, зміщення та загальну позицію прокрутки. Стан створюється через rememberLazyListState() та передається в параметр state.
Програмне керування прокруткою LazyRow здійснюється тими ж методами: animateScrollToItem для плавної анімації та scrollToItem для миттєвої прокрутки. Обидва викликаються всередині корутини. Це корисно для каруселей з кнопками «Вліво/Вправо» або для автоматичної прокрутки.
Згідно з Android Developers, 2024, LazyRow також підтримує SnapFlingBehavior — поведінку при різкій прокрутці, яка зупиняється на найближчому елементі, а не між елементами. Це створює ефект «прилипання» до елемента, звичний для каруселей і галерей.
@Composable
fun CarouselWithSnap() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
val items = listOf("A", "B", "C", "D", "E")
Column {
LazyRow(
state = listState,
flingBehavior = SnapFlingBehavior(listState),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items) { item ->
Card(modifier = Modifier.width(150.dp)) {
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Button(onClick = {
scope.launch {
listState.animateScrollToItem(0)
}
}) { Text("Щоб почати") }
}
}
}
Перший приклад — LazyRow для галереї зображень з прев'ю. Кожен елемент являє собою Box із зображенням та підписом. LazyRow ефективно обробляє десятки й сотні зображень, завантажуючи лише видимі.
@Composable
fun ImageGallery(images: List<String>) {
LazyRow(
contentPadding = PaddingValues(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(images, key = { it }) { url ->
AsyncImage(
model = url,
contentDescription = "Image",
modifier = Modifier.size(120.dp)
)
}
}
}
Другий приклад — LazyRow для списку категорій з іконками. Категорії відображаються у вигляді чіпів, і користувач може прокручувати їх горизонтально. LazyRow з spacedBy та contentPadding створює відступи між категоріями та по краях.
@Composable
fun CategoryChips(categories: List<String>) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(categories, key = { it }) { category ->
AssistChip(
onClick = {},
label = { Text(category) }
)
}
}
}
Вибір між LazyRow та Row залежить від кількості елементів. Row підходить для 5–10 елементів, які завжди видимі на екрані. LazyRow обов'язковий, коли елементів багато або їх кількість динамічна.
Row рендерить всі елементи одразу, що призводить до затримок при великій кількості елементів. LazyRow рендерить лише видимі, що робить його кращим для списків з прокруткою. Згідно з Android Developers Blog, 2024, поріг переходу — приблизно 10 елементів: якщо елементів більше, використовуйте LazyRow.
LazyRow також підтримує анімації, SnapFlingBehavior та групування через роздільники, що робить його більш гнучким для складних інтерфейсів. Row простіший і не потребує LazyListState, але не оптимізований для довгих списків.
Часті запитання
LazyRow прокручується горизонтально та розташовує елементи зліва направо, а LazyColumn — вертикально зверху вниз. Обидва використовують однакові принципи лінивого завантаження, LazyListState та DSL-функції items.
Передайте SnapFlingBehavior(listState) в параметр flingBehavior LazyRow. SnapFlingBehavior змушує LazyRow зупинятися на найближчому елементі, а не між елементами, що створює ефект прилипання для каруселей.
Відстежуйте останній видимий елемент через LazyListState.layoutInfo та підвантажуйте нові дані, коли останній елемент наближається до кінця списку. Для циклічної прокрутки використовуйте кастомну реалізацію з дублюванням елементів.
Так, LazyRow можна вкладати в LazyColumn. Це стандартний патерн для створення складних сторінок з горизонтальними каруселями всередині вертикального списку. Кожен LazyRow повинен мати фіксовану висоту для коректної роботи.
Використовуйте LazyListState.layoutInfo.visibleItemsInfo та порівняйте індекс останнього видимого елемента із загальною кількістю мінус один. Коли ці значення збігаються, LazyRow знаходиться в кінці списку.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також