Paging في قوائم Compose
اعرض البيانات الموزعة على صفحات باستخدام LazyColumn
Paging في قوائم Compose درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.
عرض البيانات المقسمة إلى صفحات في Compose
تسلّمكم طبقة البيانات قيمة من النوع Flow<PagingData<Article>>. وتحول مكتبة paging-compose هذا التدفق إلى شيء يمكن لـ LazyColumn عرضه، مع التحميل عند الطلب أثناء تمرير المستخدم.
حلقة الوصل الأساسية هي collectAsLazyPagingItems().
collectAsLazyPagingItems
استدعوا collectAsLazyPagingItems() على التدفق داخل composable. حيث يعيد كائنًا من النوع LazyPagingItems يتتبع العناصر المحمّلة وحالات التحميل، ويعيد تركيب واجهة المستخدم عند وصول الصفحات.
import androidx.paging.compose.collectAsLazyPagingItems
@Composable
fun ArticleScreen(viewModel: ArticleViewModel) {
val articles = viewModel.articles.collectAsLazyPagingItems()
ArticleList(articles)
}items() مع LazyPagingItems
استخدموا داخل LazyColumn النسخة المحملة فوقيًا من Paging للدالة items(). فهي تقرأ من LazyPagingItems وتشغل تحميل الصفحة التالية عندما يقترب المستخدم من نهاية القائمة.
قد تكون قيمة كل عنصر null عند تفعيل العناصر النائبة، لذا تعاملوا مع هذه الحالة.
import androidx.compose.foundation.lazy.LazyColumn
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.items
@Composable
fun ArticleList(articles: LazyPagingItems<Article>) {
LazyColumn {
items(articles) { article ->
if (article != null) {
ArticleRow(article)
}
}
}
}مفاتيح ثابتة للعناصر
امنحوا كل صف مفتاحًا ثابتًا حتى يتمكن Compose من تتبع العناصر بكفاءة أثناء تحميل الصفحات وتجنب إعادة التركيب غير الضرورية.
استخدموا الأداة المساعدة itemKey من Paging مع خاصية فريدة وثابتة، مثل معرّف العنصر.
import androidx.paging.compose.itemKey
LazyColumn {
items(
count = articles.itemCount,
key = articles.itemKey { it.id }
) { index ->
val article = articles[index]
if (article != null) ArticleRow(article)
}
}قراءة حالات التحميل
تعرض LazyPagingItems.loadState حالة التحميل والخطأ الحالية لثلاث عمليات:
refresh- التحميل الأولي أو التحميل بالسحب للتحديثappend- تحميل الصفحة التالية، عند التمرير إلى الأسفلprepend- تحميل الصفحة السابقة، عند التمرير إلى الأعلى
import androidx.paging.LoadState
val refresh = articles.loadState.refresh
val append = articles.loadState.append
val isInitialLoading = refresh is LoadState.Loading
val isLoadingMore = append is LoadState.Loadingحالات التحميل والفراغ بملء الشاشة
استخدموا حالة refresh للتحكم في الانطباع الأول: مؤشر تحميل في المنتصف أثناء التحميل، أو عرض خطأ عند الفشل، أو رسالة فارغة عندما لا يوجد شيء لعرضه.
when (val refresh = articles.loadState.refresh) {
is LoadState.Loading -> FullScreenSpinner()
is LoadState.Error -> FullScreenError(
message = refresh.error.message,
onRetry = { articles.retry() }
)
is LoadState.NotLoading -> {
if (articles.itemCount == 0) EmptyState()
else ArticleList(articles)
}
}مؤشر تحميل في التذييل أثناء الإلحاق
لعرض مؤشر تحميل صغير في الأسفل أثناء تحميل الصفحة التالية، أضيفوا عنصرًا إضافيًا إلى LazyColumn استنادًا إلى حالة تحميل append.
LazyColumn {
items(count = articles.itemCount, key = articles.itemKey { it.id }) { index ->
articles[index]?.let { ArticleRow(it) }
}
if (articles.loadState.append is LoadState.Loading) {
item {
Box(Modifier.fillMaxWidth().padding(16.dp), Alignment.Center) {
CircularProgressIndicator()
}
}
}
}إعادة المحاولة عند الخطأ
عند فشل عملية الإلحاق، اعرضوا صفًا لإعادة المحاولة في الأسفل. ويعيد استدعاء articles.retry() محاولة التحميل الفاشل فقط، ولا يعيد تحميل القائمة بأكملها.
val append = articles.loadState.append
if (append is LoadState.Error) {
item {
Row(Modifier.fillMaxWidth().padding(16.dp), Arrangement.Center) {
Text("Couldn't load more")
Spacer(Modifier.width(8.dp))
Button(onClick = { articles.retry() }) { Text("Retry") }
}
}
}السحب للتحديث
شغّلوا تحميلًا جديدًا باستخدام articles.refresh(). وادمجوه مع ميزة السحب للتحديث في Material 3، مع تشغيل المؤشر استنادًا إلى حالة تحميل refresh.
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
val isRefreshing = articles.loadState.refresh is LoadState.Loading
PullToRefreshBox(
isRefreshing = isRefreshing,
onRefresh = { articles.refresh() }
) {
ArticleList(articles)
}الترويسة والفواصل
يمكنكم مزج العناصر المقسمة إلى صفحات بحرية مع محتوى غير مقسم إلى صفحات في LazyColumn نفسها. أضيفوا ترويسة ثابتة أو شريط بحث أو فواصل بين الأقسام حول استدعاء items() الخاص بالعناصر المقسمة.
وبما أن كل شيء موجود في LazyColumn واحدة، يظل التمرير موحدًا وسلسًا.
LazyColumn {
item { SearchBar(query, onQueryChange) }
items(count = articles.itemCount, key = articles.itemKey { it.id }) { index ->
val article = articles[index]
if (article != null) {
ArticleRow(article)
HorizontalDivider()
}
}
if (articles.loadState.append.endOfPaginationReached) {
item { Text("You're all caught up", Modifier.padding(16.dp)) }
}
}معاينة القوائم المقسمة إلى صفحات
لا تحتاجون إلى شبكة حقيقية لمعاينات Compose والاختبارات. غلّفوا البيانات النموذجية داخل PagingData.from(...) واعرضوها كتدفق.
يتيح لكم ذلك إنشاء واجهة القائمة ومعاينتها بمعزل عن بقية النظام.
import androidx.paging.PagingData
import kotlinx.coroutines.flow.flowOf
@Preview
@Composable
fun ArticleListPreview() {
val sample = listOf(Article(1, "Hello"), Article(2, "World"))
val flow = flowOf(PagingData.from(sample))
ArticleList(flow.collectAsLazyPagingItems())
}تحقق سريع
ما الدالة التي تحول Flow<PagingData> إلى شيء يمكن لـ LazyColumn في Compose عرضه؟
مراجعة: Paging في Compose
عرضتم البيانات المقسمة إلى صفحات في Jetpack Compose:
- تربط
collectAsLazyPagingItems()التدفق بواجهة المستخدم - تحمل النسخة المحملة فوقيًا من Paging للدالة
items()المزيد من العناصر أثناء التمرير؛ تعاملوا مع العناصر النائبةnull - استخدموا
itemKey { it.id }للمفاتيح الثابتة - تتحكم
loadState.refresh/append/prependفي مؤشرات التحميل والأخطاء والحالات الفارغة - تتعامل
retry()وrefresh()مع حالات الفشل وتعيدان التحميل
التالي: دمج الشبكة وقاعدة البيانات باستخدام RemoteMediator.
الأسئلة الشائعة
هل درس «Paging في قوائم Compose» مجاني؟
نعم — نص درس «Paging في قوائم Compose» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.
ماذا ستتعلم في «Paging في قوائم Compose»؟
اعرض البيانات الموزعة على صفحات باستخدام LazyColumn تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟
لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «Paging في قوائم Compose»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟
نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا نستخدم Paging
- PagingSource وPager
- Paging في قوائم Compose
- RemoteMediator والتخزين المؤقت