LazyColumn je composable funkce v Jetpack Compose pro vytváření vertikálních seznamů s líným načítáním prvků. Na rozdíl od Column, LazyColumn vytváří a komponuje pouze prvky viditelné na obrazovce a znovu je využívá při posouvání. Podle Google Android Documentation, 2025 je LazyColumn hlavním nástrojem pro zobrazení velkých datových sad v mobilních aplikacích díky efektivní správě paměti.
Hlavní body
LazyColumn je composable funkce, která implementuje vertikální posouvatelný seznam s líným načítáním. Na rozdíl od Column, který vykresluje všechny podřízené prvky najednou, LazyColumn vytváří pouze prvky, které vstupují do oblasti zobrazení.
Mechanismus líného načítání v LazyColumn je založen na opětovném použití prvků: když se prvek během posouvání skryje, jeho kompozice a rozložení mohou být znovu použity pro nový zobrazený prvek. To šetří paměť a procesorový čas, zejména u dlouhých seznamů.
Podle Android Developers Blog, 2024 může LazyColumn efektivně zpracovávat seznamy desítek tisíc prvků bez výrazného snížení výkonu. Každý prvek v LazyColumn má klíč (key), který pomáhá Compose identifikovat a uchovávat stav prvku při změnách seznamu.
LazyColumn přijímá parametry modifier, state, contentPadding, reverseLayout, verticalArrangement a horizontalAlignment. Obsah je specifikován v lambda bloku prostřednictvím DSL funkcí items a item.
@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 = "Položka $item")
}
}
}
DSL blok LazyColumn poskytuje funkce items a item pro přidávání obsahu. items přijímá kolekci dat, klíč a tovární funkci pro vytváření prvků. item přidává jeden statický prvek do seznamu.
itemsIndexed je varianta items, která kromě dat předává také index prvku. To je užitečné, když je potřeba znát pozici prvku bez samostatného výpočtu. items(size) přijímá pouze počet prvků a továrnu bez vazby na kolekci.
Parametr key v items jednoznačně identifikuje každý prvek. Podle Material Design Guidelines, 2025 klíče zlepšují výkon při aktualizaci a animaci prvků, protože Compose může sledovat přesun nebo změnu konkrétního prvku podle klíče.
Funkce items s contentType umožňuje LazyColumn optimalizovat opětovné použití prvků různých typů. V příkladu níže jsou v jednom seznamu použita záhlaví sekcí a běžné řádky.
@Composable
fun MixedItemsList() {
LazyColumn {
item {
Text(
text = "Záhlaví",
style = MaterialTheme.typography.headlineMedium
)
}
items(
items = (1..20).toList(),
key = { it },
contentType = { "item" }
) { item ->
Text(text = "Řádek $item")
}
}
}
LazyListState je objekt stavu LazyColumn, který sleduje aktuální pozici posouvání, první viditelný prvek a odsazení. Lze jej vytvořit pomocí rememberLazyListState() a předat parametru state LazyColumn.
LazyListState poskytuje metody animateScrollToItem a scrollToItem pro programové posouvání na konkrétní prvek. animateScrollToItem vytváří plynulou animaci posouvání, zatímco scrollToItem posouvá okamžitě. Obě metody vyžadují volání uvnitř korutiny v CompositionContext.
Podle Android Developers, 2024 LazyListState také obsahuje layoutInfo, který poskytuje informace o viditelných prvcích — jejich indexech, odsazeních a velikostech. To je užitečné pro implementaci analýzy, sledování zobrazení nebo nekonečného posouvání.
V tomto příkladu je LazyColumn řízen prostřednictvím LazyListState. Tlačítko posouvá seznam k prvku s indexem 50 plynulou animací.
@Composable
fun ScrollableList() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
Column {
Button(
onClick = {
scope.launch {
listState.animateScrollToItem(50)
}
}
) {
Text("Posun na 50")
}
LazyColumn(state = listState) {
items((1..100).toList()) { item ->
Text(
text = "Položka $item",
modifier = Modifier.padding(8.dp)
)
}
}
}
}
Klíčovým faktorem výkonu LazyColumn je správné používání klíčů. Každý prvek by měl mít jedinečný stabilní klíč prostřednictvím parametru key. Bez klíčů Compose nemůže správně znovu používat prvky při změně dat, což vede k rekompozici.
contentType informuje LazyColumn, které prvky mají stejný typ rozložení. Když dva prvky se stejným contentType vstoupí do oblasti zpracování, LazyColumn může znovu použít jejich rozložení bez rekompozice. Podle Android Developers Blog, 2024 contentType zlepšuje výkon o 30–50% v seznamech s různými typy prvků.
Pro LazyColumn je také důležité vyhýbat se nestabilním parametrům v továrních funkcích. Pokaždé, když se parametr prvku změní, Compose tento prvek rekomponuje. Použití remember a derivedStateOf pro stabilní hodnoty snižuje počet rekompozic.
| Faktor | Dopad | Doporučení |
|---|---|---|
| Klíče (key) | Klíčový | Vždy nastavte jedinečný stabilní key pro items |
| contentType | Významný | Uveďte typ prvku pro optimalizaci opětovného použití |
| Velikost prvků | Střední | Používejte pevné velikosti kde je to možné |
| Vnořené seznamy | Kritický | Vyhněte se LazyColumn uvnitř LazyColumn — použijte LazyVerticalGrid |
stickyHeader je DSL funkce LazyColumn, která přichytí záhlaví sekce k horní části seznamu při posouvání. Když následující sekce dosáhne vrcholu, její záhlaví nahradí aktuální. Toto chování je uživatelům známé ze seznamů kontaktů a kalendářů.
stickyHeader přijímá klíč a tovární funkci, podobně jako item. Na rozdíl od běžného item, stickyHeader zůstává viditelný při posouvání obsahu své sekce. Když je sekce zcela posunuta, záhlaví následující sekce vytlačí předchozí.
Podle Material Design Guidelines, 2025 sticky header zlepšuje navigaci v dlouhých seznamech a snižuje kognitivní zátěž uživatele. Pro implementaci sticky header stačí zabalit záhlaví sekce do stickyHeader na správné pozici vůči prvkům items.
@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))
}
}
}
}
Často kladené dotazy
Column vykresluje všechny prvky najednou a je vhodný pro seznamy do 20–30 prvků. LazyColumn vytváří pouze viditelné prvky a znovu je využívá při posouvání, což umožňuje práci s tisíci prvků bez ztráty výkonu.
Použijte Arrangement.spacedBy v parametru verticalArrangement nebo funkce items s oddělovačem přes index. Pro složité oddělovače přidejte samostatný item s Divider() mezi prvky seznamu.
LazyColumn se automaticky rekomponuje při změně kolekce dat, pokud se používají stabilní klíče. Změny dat detekované prostřednictvím mutableStateListOf nebo StateFlow vedou k překreslení pouze změněných prvků.
Přímé vnoření LazyColumn do LazyColumn se nedoporučuje — oba mají nezávislé posouvání, což vytváří konflikt gest. Místo toho použijte běžný Column s LazyColumn uvnitř posouvatelné sekce nebo LazyVerticalGrid pro mřížky.
Použijte LazyListState.layoutInfo.visibleItemsInfo a porovnejte index posledního viditelného prvku s celkovým počtem prvků. Pro nekonečné posouvání sledujte, kdy se poslední viditelný prvek blíží konci seznamu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také