Libary Paging melacak status permintaan pemuatan untuk data yang di-page dan menampilkannya
melalui class LoadState.
Sinyal LoadState terpisah diberikan untuk setiapLoadType dan jenis sumber data
(PagingSource atau
RemoteMediator). Objek
CombinedLoadStates
yang diberikan oleh pemroses berisi informasi tentang status pemuatan
dari semua sinyal ini. Anda dapat menggunakan informasi mendetail ini untuk menampilkan
indikator pemuatan yang sesuai untuk pengguna Anda.
Status pemuatan
Library Paging menampilkan status pemuatan untuk digunakan di UI melalui
objek LoadState. Objek LoadState mengambil salah satu dari tiga bentuk, bergantung pada
status pemuatan saat ini:
- Jika tidak ada operasi pemuatan yang aktif dan tidak ada error,
LoadStateadalah objekLoadState.NotLoading. Subclass ini juga menyertakan propertiendOfPaginationReached, yang menunjukkan apakah akhir penomoran halaman telah tercapai. - Jika ada operasi pemuatan yang aktif,
LoadStateadalah objekLoadState.Loading. - Jika ada error,
LoadStateadalah objekLoadState.Error.
Akses status ini melalui properti loadState dari wrapper
LazyPagingItems Anda. Anda dapat menggunakan status ini dengan dua cara: menangani
visibilitas konten utama (seperti spinner pemuatan ulang layar penuh) atau menyisipkan
item pemuatan langsung ke aliran LazyColumn (seperti spinner footer).
Mengakses status pemuatan dengan pemroses
Untuk memantau status pemuatan di UI Anda, gunakan properti loadState
yang disediakan oleh wrapper LazyPagingItems. Objek ini menampilkan objek
CombinedLoadStates yang memungkinkan Anda bereaksi terhadap perilaku pemuatan untuk
peristiwa muat ulang, tambahkan, atau tambahkan di depan.
Dalam contoh berikut, UI menampilkan indikator lingkaran berputar untuk pemuatan atau pesan error bergantung pada status pemuatan refresh (awal) saat ini:
@Composable fun UserListScreen(viewModel: UserViewModel) { val pagingItems = viewModel.flow.collectAsLazyPagingItems() Box(modifier = Modifier.fillMaxSize()) { // Show the list content LazyColumn { items(pagingItems.itemCount) { index -> UserItem(pagingItems[index]) } } // Handle the loading state when (val state = pagingItems.loadState.refresh) { is LoadState.Loading -> { CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) } is LoadState.Error -> { ErrorButton( message = state.error.message ?: "Unknown error", onClick = { pagingItems.retry() }, modifier = Modifier.align(Alignment.Center) ) } else -> {} // No separate view needed for success/not loading } } }
Untuk mengetahui informasi selengkapnya tentang LazyPagingItems, lihat Set data besar (paging).
Menambahkan header dan footer pemuatan
Untuk menampilkan indikator pemuatan di awal atau akhir daftar (bertindak sebagai
header atau footer), tambahkan blok item khusus untuk status tersebut
dalam cakupan LazyColumn.
Anda dapat memantau status penambahan untuk header dan status penambahan untuk
footer menggunakan objek CombinedLoadStates.
Dalam contoh berikut, daftar menampilkan status progres atau tombol coba lagi di bagian bawah daftar saat lebih banyak data diambil:
@Composable fun UserList(viewModel: UserViewModel) { val pagingItems = viewModel.pager.flow.collectAsLazyPagingItems() LazyColumn { // 1. Header (Prepend state) // Useful if you support bidirectional paging or jumping to the middle item { val prependState = pagingItems.loadState.prepend if (prependState is LoadState.Loading) { LoadingItem() } else if (prependState is LoadState.Error) { ErrorItem( message = prependState.error.message ?: "Error", onClick = { pagingItems.retry() } ) } } // 2. Main Data items(pagingItems.itemCount) { index -> UserItem(pagingItems[index]) } // 3. Footer (Append state) // Shows when the user scrolls to the bottom and more data is loading item { val appendState = pagingItems.loadState.append if (appendState is LoadState.Loading) { LoadingItem() } else if (appendState is LoadState.Error) { ErrorItem( message = appendState.error.message ?: "Error", onClick = { pagingItems.retry() } ) } } } } @Composable fun LoadingItem() { Box(modifier = Modifier.fillMaxWidth().padding(16.dp), contentAlignment = Alignment.Center) { CircularProgressIndicator() } } @Composable fun ErrorItem(message: String, onClick: () -> Unit) { Column( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = message, color = Color.Red) Button(onClick = onClick) { Text("Retry") } } }
Mengakses informasi status pemuatan tambahan
Seperti yang ditunjukkan dalam contoh sebelumnya, memanggil pagingItems.loadState.refresh sangat praktis. Namun, hal ini mengaburkan perbedaan antara pemuatan dari database
lokal (PagingSource) dan
jaringan (RemoteMediator).
Hal ini dapat menyebabkan UI menampilkan indikator lingkaran berputar pemuatan secara singkat meskipun data yang di-cache
langsung tersedia.
Untuk kontrol yang presisi, seperti menampilkan indikator lingkaran berputar pemuatan hanya saat database lokal kosong dan sinkronisasi jaringan aktif, akses properti source dan mediator secara langsung dalam composable Anda.
val loadState = pagingItems.loadState val isSyncing = loadState.mediator?.refresh is LoadState.Loading val isLocalEmpty = loadState.source.refresh is LoadState.NotLoading && pagingItems.itemSnapshotList.items.isEmpty() if (isSyncing && isLocalEmpty) { FullScreenLoading() } else { UserList(pagingItems) if (isSyncing) { TopOverlaySpinner() } }
Merespons perubahan status pemuatan
Anda mungkin perlu memicu efek samping satu kali berdasarkan perubahan status pemuatan,
seperti men-scroll ke bagian atas daftar atau menampilkan Snackbar saat penyegaran
selesai.
Gunakan snapshotFlow di dalam LaunchedEffect untuk mengamati perubahan status sebagai
aliran. Hal ini memungkinkan Anda menerapkan operator Flow standar seperti filter
dan distinctUntilChanged untuk mengisolasi peristiwa tertentu.
val listState = rememberLazyListState() LaunchedEffect(pagingItems) { // 1. Convert the state to a Flow snapshotFlow { pagingItems.loadState.refresh } // 2. Filter for the specific event (Refresh completed successfully) .distinctUntilChanged() .filter { it is LoadState.NotLoading } .collect { // 3. Trigger the side effect listState.animateScrollToItem(0) } }
Referensi lainnya
Untuk mengetahui informasi selengkapnya tentang library Paging dan status pemuatan, lihat referensi berikut.
Dokumentasi
Melihat konten
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Ringkasan library paging