LazyColumn, Jetpack Compose’da öğelerin tembel yüklemesiyle dikey listeler oluşturmak için bir composable işlevidir. Column’un aksine, LazyColumn yalnızca ekranda görünür öğeleri oluşturur ve birleştirir, kaydırma sırasında bunları yeniden kullanır. Google Android Documentation, 2025’e göre LazyColumn, verimli bellek yönetimi sayesinde mobil uygulamalarda büyük veri kümelerini görüntülemek için birincil araçtır.
Önemli Noktalar
LazyColumn, tembel yükleme ile dikey kaydırılabilir bir liste uygulayan bir composable işlevidir. Tüm alt öğeleri bir kerede işleyen Column’un aksine, LazyColumn yalnızca görüntü alanı içindeki öğeleri oluşturur.
LazyColumn’daki tembel yükleme mekanizması, öğe yeniden kullanımına dayanır: kaydırma sırasında bir öğe gizlendiğinde, bileşimi ve düzeni yeni görüntülenen bir öğe için yeniden kullanılabilir. Bu, özellikle uzun listelerde bellek ve CPU süresinden tasarruf sağlar.
Android Developers Blog, 2024’e göre LazyColumn, önemli performans düşüşü olmadan on binlerce öğeden oluşan listeleri verimli bir şekilde işleyebilir. LazyColumn’daki her öğenin, liste değiştiğinde Compose’un öğenin durumunu tanımlamasına ve korumasına yardımcı olan bir anahtarı (key) vardır.
LazyColumn, modifier, state, contentPadding, reverseLayout, verticalArrangement ve horizontalAlignment parametrelerini kabul eder. İçerik, DSL işlevleri items ve item aracılığıyla lambda bloğunda tanımlanır.
@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 = "Öğe $item")
}
}
}
LazyColumn’un DSL bloğu, içerik eklemek için items ve item işlevlerini sağlar. items, öğeler oluşturmak için bir veri koleksiyonu, bir anahtar ve fabrika işlevi kabul eder. item, listeye tek bir statik öğe ekler.
itemsIndexed, verilere ek olarak öğe dizinini ileten items’ın bir varyantıdır. Bu, ayrı bir hesaplama olmadan öğenin konumunu bilmeniz gerektiğinde kullanışlıdır. items(size), bir koleksiyona bağlanmadan yalnızca öğe sayısını ve bir fabrikayı kabul eder.
items’daki key parametresi her öğeyi benzersiz şekilde tanımlar. Material Design Guidelines, 2025’e göre anahtarlar, öğeleri güncellerken ve canlandırırken performansı artırır çünkü Compose, anahtarı aracılığıyla belirli bir öğenin hareketini veya değişimini izleyebilir.
contentType ile items işlevi, LazyColumn’un farklı türdeki öğelerin yeniden kullanımını optimize etmesine olanak tanır. Aşağıdaki örnekte, tek bir listede bölüm başlıkları ve normal satırlar kullanılmıştır.
@Composable
fun MixedItemsList() {
LazyColumn {
item {
Text(
text = "Başlık",
style = MaterialTheme.typography.headlineMedium
)
}
items(
items = (1..20).toList(),
key = { it },
contentType = { "item" }
) { item ->
Text(text = "Satır $item")
}
}
}
LazyListState, geçerli kaydırma konumunu, ilk görünür öğeyi ve kaymayı izleyen bir LazyColumn durum nesnesidir. rememberLazyListState() aracılığıyla oluşturulabilir ve LazyColumn’un state parametresine aktarılabilir.
LazyListState, belirli bir öğeye programatik kaydırma için animateScrollToItem ve scrollToItem yöntemlerini sağlar. animateScrollToItem yumuşak bir kaydırma animasyonu oluştururken, scrollToItem anında kaydırır. Her iki yöntem de CompositionContext içinde bir coroutine içinde çağrılmayı gerektirir.
Android Developers, 2024’e göre LazyListState ayrıca görünür öğeler hakkında bilgi sağlayan layoutInfo içerir — dizinleri, kaymaları ve boyutları. Bu, analitik, görüntüleme takibi veya sonsuz kaydırma uygulamak için kullanışlıdır.
Bu örnekte, LazyColumn LazyListState aracılığıyla kontrol edilir. Bir düğme, yumuşak bir animasyonla listeyi 50 dizinindeki öğeye kaydırır.
@Composable
fun ScrollableList() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
Column {
Button(
onClick = {
scope.launch {
listState.animateScrollToItem(50)
}
}
) {
Text("50’ye kaydır")
}
LazyColumn(state = listState) {
items((1..100).toList()) { item ->
Text(
text = "Öğe $item",
modifier = Modifier.padding(8.dp)
)
}
}
}
}
LazyColumn’un temel performans faktörü, anahtarların doğru kullanımıdır. Her öğe, key parametresi aracılığıyla benzersiz ve kararlı bir anahtara sahip olmalıdır. Anahtarlar olmadan, Compose veriler değiştiğinde öğeleri doğru şekilde yeniden kullanamaz ve bu da yeniden bileşime yol açar.
contentType, LazyColumn’a hangi öğelerin aynı düzen türüne sahip olduğunu söyler. Aynı contentType’a sahip iki öğe geri dönüşüm havuzuna girdiğinde, LazyColumn yeniden bileşim olmadan düzenlerini yeniden kullanabilir. Android Developers Blog, 2024’e göre contentType, farklı öğe türlerine sahip listelerde performansı %30–50 oranında artırır.
LazyColumn için fabrika işlevlerinde kararsız parametrelerden kaçınmak da önemlidir. Bir öğe parametresi her değiştiğinde, Compose bu öğeyi yeniden birleştirir. Kararlı değerler için remember ve derivedStateOf kullanmak yeniden bileşim sayısını azaltır.
| Faktör | Etki | Öneri |
|---|---|---|
| Anahtarlar (key) | Kritik | items için her zaman benzersiz kararlı bir key belirleyin |
| contentType | Önemli | Yeniden kullanımı optimize etmek için öğe türünü belirtin |
| Öğe boyutu | Orta | Mümkün olduğunda sabit boyutlar kullanın |
| İç içe listeler | Kritik | LazyColumn içinde LazyColumn’dan kaçının — LazyVerticalGrid kullanın |
stickyHeader, kaydırma sırasında bir bölüm başlığını listenin üst kısmına sabitleyen bir LazyColumn DSL işlevidir. Bir sonraki bölüm üste ulaştığında, başlığı mevcut başlığın yerini alır. Bu davranış, kullanıcılara kişi listeleri ve takvimlerden tanıdık gelir.
stickyHeader, item’a benzer şekilde bir anahtar ve fabrika işlevi kabul eder. Normal bir item’ın aksine, stickyHeader bölümünün içeriği arasında kaydırma yaparken görünür kalır. Bir bölüm tamamen kaydırıldığında, sonraki bölümün başlığı önceki başlığı dışarı iter.
Material Design Guidelines, 2025’e göre sticky header’lar uzun listelerde gezinmeyi iyileştirir ve kullanıcı üzerindeki bilişsel yükü azaltır. Bir sticky header uygulamak için, items öğelerine göre doğru konumda bir bölüm başlığını stickyHeader ile sarmanız yeterlidir.
@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))
}
}
}
}
Sıkça Sorulan Sorular
Column tüm öğeleri bir kerede işler ve 20–30 öğeye kadar listeler için uygundur. LazyColumn yalnızca görünür öğeleri oluşturur ve kaydırma sırasında bunları yeniden kullanır, böylece performans kaybı olmadan binlerce öğeyle çalışmanıza olanak tanır.
verticalArrangement parametresinde Arrangement.spacedBy kullanın veya dizin aracılığıyla ayırıcılı items işlevlerini kullanın. Karmaşık ayırıcılar için, liste öğeleri arasına Divider() içeren ayrı bir item ekleyin.
LazyColumn, kararlı anahtarlar kullanılıyorsa, veri koleksiyonu değiştiğinde otomatik olarak yeniden birleşir. mutableStateListOf veya StateFlow aracılığıyla algılanan veri değişiklikleri, yalnızca değişen öğelerin yeniden çizilmesine neden olur.
LazyColumn içine doğrudan LazyColumn yerleştirilmesi önerilmez — her ikisinin de bağımsız kaydırması vardır ve bu, jest çakışmalarına neden olur. Bunun yerine, kaydırılabilir bir Section içinde LazyColumn ile normal bir Column veya ızgaralar için LazyVerticalGrid kullanın.
LazyListState.layoutInfo.visibleItemsInfo kullanın ve son görünür öğenin dizinini toplam öğe sayısıyla karşılaştırın. Sonsuz kaydırma için, son görünür öğenin listenin sonuna ne zaman yaklaştığını izleyin.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun