ComposeのリストでPagingを使う
LazyColumnでページングされたデータを描画します。
「ComposeのリストでPagingを使う」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全4レッスンが含まれています。
Compose でページングされたデータを表示する
データレイヤーからFlow<PagingData<Article>>が渡されます。paging-composeライブラリは、このFlowをLazyColumnで表示できる形式に変換します。ユーザーのスクロールに応じたオンデマンド読み込みにも対応しています。
その橋渡しを担うのがcollectAsLazyPagingItems()です。
collectAsLazyPagingItems
コンポーザブル内で、Flowに対してcollectAsLazyPagingItems()を呼び出します。読み込まれた項目と読み込み状態を追跡するLazyPagingItemsオブジェクトが返され、ページが到着するたびにUIが再コンポーズされます。
import androidx.paging.compose.collectAsLazyPagingItems
@Composable
fun ArticleScreen(viewModel: ArticleViewModel) {
val articles = viewModel.articles.collectAsLazyPagingItems()
ArticleList(articles)
}LazyPagingItems で items() を使う
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がページの読み込みをまたいで項目を効率的に追跡でき、不要な再コンポーズを防げます。
項目IDのような一意で安定したプロパティとともに、PagingのitemKeyヘルパーを使用してください。
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は、次の3つの操作について現在の読み込み状態とエラー状態を公開します。
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)
}
}追加読み込み中のフッタースピナー
次のページの読み込み中に画面下部へ小さなスピナーを表示するには、appendの読み込み状態に応じてLazyColumnに追加の項目を挿入します。
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()の前後に、固定ヘッダー、検索バー、セクション区切りなどを追加できます。
すべてが1つの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(...)でラップし、Flowとして公開します。
これにより、リストUIを他の処理から分離して構築・プレビューできます。
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>を、ComposeのLazyColumnで表示できる形式に変換する関数はどれですか?
まとめ:Compose での Paging
Jetpack Composeでページングされたデータを表示しました。
collectAsLazyPagingItems()がFlowとUIを橋渡しする- Pagingの
items()オーバーロードはスクロールに応じて追加データを読み込む。nullのプレースホルダーを処理する - 安定したキーには
itemKey { it.id }を使用する loadState.refresh/append/prependでスピナー、エラー、空状態を制御するretry()とrefresh()で失敗から復旧し、再読み込みする
次は、RemoteMediatorを使ってネットワークとデータベースを組み合わせます。
よくある質問
「ComposeのリストでPagingを使う」レッスンは無料ですか?
はい。「ComposeのリストでPagingを使う」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全4レッスンが含まれています。
「ComposeのリストでPagingを使う」で何を学びますか?
LazyColumnでページングされたデータを描画します。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Android Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「ComposeのリストでPagingを使う」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAndroid Academyレッスンでコードを書いて実行できますか?
はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Pagingが必要な理由
- PagingSourceとPager
- ComposeのリストでPagingを使う
- RemoteMediatorとキャッシュ