LazyRow — este o funcție composable în Jetpack Compose pentru crearea listelor orizontale cu încărcare lentă a elementelor. Spre deosebire de Row, LazyRow creează doar elementele vizibile și le reutilizează în timpul derulării orizontale. Conform Google Android Documentation, 2025, LazyRow este echivalentul orizontal al LazyColumn și este eficient pentru carusele, galerii și meniuri orizontale în aplicații mobile.
Puncte cheie
LazyRow — este o funcție composable care implementează o listă orizontală derulabilă cu încărcare lentă a elementelor. Spre deosebire de Row, care redezează toate elementele copil simultan, LazyRow creează doar elementele vizibile în zona de afișare.
LazyRow funcționează după același principiu ca LazyColumn, dar aranjează elementele orizontal. La derularea la stânga sau la dreapta, elementele care au ieșit din zona vizibilă sunt reutilizate pentru afișarea celor noi. Acest lucru este critic pentru galeriile cu un număr mare de imagini sau liste lungi de categorii.
Conform Android Developers Blog, 2024, LazyRow utilizează aceeași arhitectură LazyList ca LazyColumn, inclusiv LazyListState, mecanismul de reutilizare prin Pool și suportul pentru diferite tipuri de elemente. Eficiența maximă se atinge cu utilizarea unei înălțimi fixe a elementelor.
LazyRow acceptă parametrii modifier, state, contentPadding, reverseLayout, horizontalArrangement și verticalAlignment. Conținutul este definit prin funcțiile DSL items și item, similar cu 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 gestionează distribuția elementelor de-a lungul axei orizontale în interiorul LazyRow. Sunt disponibile aceleași valori Arrangement ca în Row: Start, Center, End, SpaceBetween, SpaceEvenly, SpaceAround și spacedBy cu spațiere personalizată.
contentPadding adaugă margini la capetele containerului LazyRow. Spre deosebire de Modifier.padding, contentPadding este luat în considerare la derulare: primul element va avea margine de la capătul stâng, ultimul — de la capătul drept. Conform Material Design Guidelines, 2025, contentPadding este obligatoriu pentru carusele și galerii, pentru ca primul și ultimul element să nu se lipească de marginile ecranului.
verticalAlignment aliniază elementele pe verticală în interiorul LazyRow. Implicit se utilizează Alignment.Top. Pentru centrarea elementelor de înălțimi diferite utilizați Alignment.CenterVertically, util pentru carusele cu imagini de proporții diferite.
| Parametru | Descriere | Valoare implicită |
|---|---|---|
| horizontalArrangement | Distribuția elementelor pe orizontală | Arrangement.Start |
| contentPadding | Marginile containerului | PaddingValues(0.dp) |
| verticalAlignment | Alinierea verticală | Alignment.Top |
| reverseLayout | Ordinea inversă a elementelor | false |
| userScrollEnabled | Permiterea derulării de către utilizator | true |
LazyListState pentru LazyRow funcționează identic ca pentru LazyColumn: urmărește primul element vizibil, deplasarea și poziția generală de derulare. Starea este creată prin rememberLazyListState() și transmisă în parametrul state.
Controlul programatic al derulării LazyRow se face prin aceleași metode: animateScrollToItem pentru animație lină și scrollToItem pentru derulare instantanee. Ambele sunt apelate în interiorul unei corutine. Acest lucru este util pentru carusele cu butoane „Stânga/Dreapta" sau pentru derulare automată.
Conform Android Developers, 2024, LazyRow acceptă și SnapFlingBehavior — comportamentul la derularea bruscă care se oprește pe cel mai apropiat element, nu între elemente. Acesta creează un efect de „lipire" de element, familiar pentru carusele și galerii.
@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("Pentru a începe") }
}
}
}
Primul exemplu — LazyRow pentru o galerie de imagini cu previzualizări. Fiecare element este un Box cu imagine și legendă. LazyRow gestionează eficient zeci și sute de imagini, încărcând doar cele vizibile.
@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)
)
}
}
}
Al doilea exemplu — LazyRow pentru o listă de categorii cu pictograme. Categoriile sunt afișate sub formă de cipuri, iar utilizatorul le poate derula orizontal. LazyRow cu spacedBy și contentPadding creează spații între categorii și la margini.
@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) }
)
}
}
}
Alegerea între LazyRow și Row depinde de numărul de elemente. Row este potrivit pentru 5–10 elemente care sunt întotdeauna vizibile pe ecran. LazyRow este obligatoriu când elementele sunt multe sau numărul lor este dinamic.
Row redezează toate elementele simultan, ceea ce duce la întârzieri la un număr mare de elemente. LazyRow redezează doar elementele vizibile, ceea ce îl face preferabil pentru liste cu derulare. Conform Android Developers Blog, 2024, pragul de trecere este de aproximativ 10 elemente: dacă sunt mai multe, utilizați LazyRow.
LazyRow acceptă și animații, SnapFlingBehavior și gruparea prin separatoare, ceea ce îl face mai flexibil pentru interfețe complexe. Row este mai simplu și nu necesită LazyListState, dar nu este optimizat pentru liste lungi.
Întrebări frecvente
LazyRow se derulează orizontal și aranjează elementele de la stânga la dreapta, iar LazyColumn — vertical de sus în jos. Ambele utilizează aceleași principii de încărcare lentă, LazyListState și funcțiile DSL items.
Transmiteți SnapFlingBehavior(listState) în parametrul flingBehavior al LazyRow. SnapFlingBehaviour face ca LazyRow să se oprească pe cel mai apropiat element, nu între elemente, creând un efect de lipire pentru carusele.
Urmăriți ultimul element vizibil prin LazyListState.layoutInfo și încărcați date noi când ultimul element se apropie de sfârșitul listei. Pentru derulare ciclică utilizați o implementare personalizată cu duplicarea elementelor.
Da, LazyRow poate fi imbricat în LazyColumn. Acesta este un model standard pentru crearea paginilor complexe cu carusele orizontale în interiorul unei liste verticale. Fiecare LazyRow trebuie să aibă o înălțime fixă pentru funcționare corectă.
Utilizați LazyListState.layoutInfo.visibleItemsInfo și comparați indexul ultimului element vizibil cu numărul total minus unu. Când aceste valori coincid, LazyRow se află la sfârșitul listei.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și