LazyRow — е composable функция в Jetpack Compose за създаване на хоризонтални списъци с мързеливо зареждане на елементи. За разлика от Row, LazyRow създава само видимите елементи и ги използва повторно при хоризонтално превъртане. Според Google Android Documentation, 2025, LazyRow е хоризонталният аналог на LazyColumn и е ефективен за въртележки, галерии и хоризонтални менюта в мобилни приложения.
Основни точки
LazyRow — е composable функция, която имплементира хоризонтален превъртащ се списък с мързеливо зареждане на елементи. За разлика от 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. SnapFlingBehaviour кара LazyRow да спира на най-близкия елемент, а не между елементите, което създава ефект на залепване за въртележки.
Проследявайте последния видим елемент чрез LazyListState.layoutInfo и зареждайте нови данни, когато последният елемент се приближава до края на списъка. За циклично превъртане използвайте персонализирана имплементация с дублиране на елементи.
Да, LazyRow може да бъде вложен в LazyColumn. Това е стандартен модел за създаване на сложни страници с хоризонтални въртележки вътре във вертикален списък. Всеки LazyRow трябва да има фиксирана височина за коректна работа.
Използвайте LazyListState.layoutInfo.visibleItemsInfo и сравнете индекса на последния видим елемент с общия брой минус едно. Когато тези стойности съвпаднат, LazyRow е в края на списъка.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също