LazyColumn یک تابع composable در Jetpack Compose برای ایجاد لیستهای عمودی با بارگذاری تنبل عناصر است. بر خلاف Column، LazyColumn فقط عناصر قابل مشاهده روی صفحه را ایجاد و ترکیب میکند و هنگام اسکرول آنها را مجدداً استفاده میکند. به گفته Google Android Documentation, 2025, LazyColumn ابزار اصلی برای نمایش مجموعه دادههای بزرگ در برنامههای موبایل به دلیل مدیریت کارآمد حافظه است.
نکات اصلی
LazyColumn یک تابع composable است که یک لیست عمودی قابل اسکرول با بارگذاری تنبل را پیادهسازی میکند. بر خلاف Column که همه عناصر فرزند را یکباره رندر میکند، LazyColumn فقط عناصری را که در ناحیه نمایش قرار میگیرند ایجاد میکند.
مکانیزم بارگذاری تنبل در LazyColumn بر اساس استفاده مجدد از عناصر است: وقتی عنصری در حین اسکرول پنهان میشود، ترکیب و چیدمان آن میتواند برای عنصر جدید نمایش داده شده مجدداً استفاده شود. این کار به ویژه در لیستهای طولانی در حافظه و زمان پردازنده صرفهجویی میکند.
به گفته Android Developers Blog, 2024, LazyColumn میتواند لیستهای دهها هزار عنصری را بدون کاهش قابل توجه عملکرد به طور مؤثر پردازش کند. هر عنصر در LazyColumn یک کلید (key) دارد که به Compose کمک میکند هنگام تغییرات لیست، عنصر را شناسایی کرده و وضعیت آن را حفظ کند.
LazyColumn پارامترهای modifier, state, contentPadding, reverseLayout, verticalArrangement و horizontalAlignment را میپذیرد. محتوا در بلوک لامبدا از طریق توابع DSL items و 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 = "عنصر $item")
}
}
}
بلوک DSL LazyColumn توابع items و item را برای افزودن محتوا فراهم میکند. items مجموعه داده، کلید و تابع کارخانه برای ایجاد عناصر را میپذیرد. item یک عنصر ایستا به لیست اضافه میکند.
itemsIndexed نوعی از items است که علاوه بر داده، اندیس عنصر را نیز منتقل میکند. این زمانی مفید است که موقعیت عنصر بدون محاسبه جداگانه مورد نیاز باشد. items(size) فقط تعداد عناصر و کارخانه را بدون وابستگی به مجموعه میپذیرد.
پارامتر key در items هر عنصر را به طور یکتا شناسایی میکند. به گفته Material Design Guidelines, 2025, کلیدها عملکرد را در هنگام بهروزرسانی و انیمیشن عناصر بهبود میبخشند، زیرا Compose میتواند جابجایی یا تغییر یک عنصر خاص را از طریق کلید ردیابی کند.
تابع items با contentType به LazyColumn اجازه میدهد استفاده مجدد از عناصر با انواع مختلف را بهینه کند. در مثال زیر، در یک لیست از عنوانبخشها و ردیفهای معمولی استفاده شده است.
@Composable
fun MixedItemsList() {
LazyColumn {
item {
Text(
text = "عنوان",
style = MaterialTheme.typography.headlineMedium
)
}
items(
items = (1..20).toList(),
key = { it },
contentType = { "item" }
) { item ->
Text(text = "ردیف $item")
}
}
}
LazyListState یک شیء وضعیت LazyColumn است که موقعیت فعلی اسکرول، اولین عنصر قابل مشاهده و جابجایی را ردیابی میکند. این شیء میتواند از طریق rememberLazyListState() ایجاد شده و به پارامتر state LazyColumn منتقل شود.
LazyListState متدهای animateScrollToItem و scrollToItem را برای اسکرول برنامهریزی شده به یک عنصر خاص فراهم میکند. animateScrollToItem یک انیمیشن روان اسکرول ایجاد میکند و scrollToItem بلافاصله اسکرول میکند. هر دو متد نیاز به فراخوانی در داخل یک کوروتین در CompositionContext دارند.
به گفته Android Developers, 2024, LazyListState همچنین شامل layoutInfo است که اطلاعاتی درباره عناصر قابل مشاهده — اندیسها، جابجاییها و اندازههای آنها — ارائه میدهد. این برای پیادهسازی تحلیل، ردیابی بازدیدها یا اسکرول بینهایت مفید است.
در این مثال LazyColumn از طریق LazyListState کنترل میشود. دکمه لیست را با انیمیشن روان به عنصر با اندیس 50 اسکرول میکند.
@Composable
fun ScrollableList() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
Column {
Button(
onClick = {
scope.launch {
listState.animateScrollToItem(50)
}
}
) {
Text("اسکرول به 50")
}
LazyColumn(state = listState) {
items((1..100).toList()) { item ->
Text(
text = "عنصر $item",
modifier = Modifier.padding(8.dp)
)
}
}
}
}
عامل کلیدی عملکرد LazyColumn استفاده صحیح از کلیدها است. هر عنصر باید یک کلید پایدار منحصر به فرد از طریق پارامتر key داشته باشد. بدون کلید، Compose نمیتواند هنگام تغییر داده از عناصر مجدداً استفاده کند که منجر به ترکیب مجدد میشود.
contentType به LazyColumn اطلاع میدهد کدام عناصر نوع چیدمان یکسانی دارند. وقتی دو عنصر با contentType یکسان وارد منطقه پردازش میشوند، LazyColumn میتواند بدون ترکیب مجدد از چیدمان آنها مجدداً استفاده کند. به گفته Android Developers Blog, 2024, contentType عملکرد را در لیستهایی با انواع مختلف عناصر 30–50% بهبود میبخشد.
برای LazyColumn همچنین اجتناب از پارامترهای ناپایدار در توابع کارخانه مهم است. هر بار که پارامتر یک عنصر تغییر میکند، Compose آن عنصر را دوباره ترکیب میکند. استفاده از remember و derivedStateOf برای مقادیر پایدار تعداد ترکیبهای مجدد را کاهش میدهد.
| عامل | تأثیر | توصیه |
|---|---|---|
| کلیدها (key) | کلیدی | همیشه یک key پایدار منحصر به فرد برای items تعیین کنید |
| contentType | قابل توجه | نوع عنصر را برای بهینهسازی استفاده مجدد مشخص کنید |
| اندازه عناصر | متوسط | در صورت امکان از اندازههای ثابت استفاده کنید |
| لیستهای تو در تو | بحرانی | از LazyColumn درون LazyColumn خودداری کنید — از LazyVerticalGrid استفاده کنید |
stickyHeader تابع DSL LazyColumn است که عنوان بخش را هنگام اسکرول در بالای لیست ثابت میکند. وقتی بخش بعدی به بالا میرسد، عنوان آن جایگزین عنوان فعلی میشود. این رفتار برای کاربران از لیست مخاطبین و تقویمها آشناست.
stickyHeader مانند item یک کلید و تابع کارخانه میپذیرد. بر خلاف item معمولی، stickyHeader هنگام اسکرول محتوای بخش خود قابل مشاهده میماند. وقتی بخش به طور کامل اسکرول شد، عنوان بخش بعدی عنوان قبلی را کنار میزند.
به گفته Material Design Guidelines, 2025, sticky header ناوبری را در لیستهای طولانی بهبود میبخشد و بار شناختی کاربر را کاهش میدهد. برای پیادهسازی sticky header کافی است عنوان بخش را در موقعیت صحیح نسبت به عناصر items در stickyHeader قرار دهید.
@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))
}
}
}
}
سوالات متداول
Column همه عناصر را یکباره رندر کرده و برای لیستهای تا 20–30 عنصر مناسب است. LazyColumn فقط عناصر قابل مشاهده را ایجاد کرده و هنگام اسکرول آنها را مجدداً استفاده میکند که امکان کار با هزاران عنصر بدون افت عملکرد را فراهم میکند.
از Arrangement.spacedBy در پارامتر verticalArrangement یا توابع items با جداکننده از طریق اندیس استفاده کنید. برای جداکنندههای پیچیده، یک item جداگانه با Divider() بین عناصر لیست اضافه کنید.
LazyColumn هنگام تغییر مجموعه داده در صورت استفاده از کلیدهای پایدار به طور خودکار ترکیب مجدد میشود. تغییرات داده که از طریق mutableStateListOf یا StateFlow تشخیص داده میشوند منجر به بازترسیم فقط عناصر تغییر یافته میشوند.
قرار دادن مستقیم LazyColumn درون LazyColumn توصیه نمیشود — هر دو اسکرول مستقل دارند که تضاد ژست ایجاد میکند. به جای آن از Column معمولی با LazyColumn درون بخش قابل اسکرول یا LazyVerticalGrid برای شبکهها استفاده کنید.
از LazyListState.layoutInfo.visibleItemsInfo استفاده کنید و اندیس آخرین عنصر قابل مشاهده را با تعداد کل عناصر مقایسه کنید. برای اسکرول بینهایت، زمانی که آخرین عنصر قابل مشاهده به انتهای لیست نزدیک میشود را ردیابی کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید