今回はJetpackComposeでページングとして
Paging3を利用したときに学んだことをまとめる
・パッケージ
paging-composeのstableがなくてウケる
rc版ならまぁ問題ないと思うけど
https://zenn.dev/sobya/articles/1fdf9c92bb4404
implementation "androidx.paging:paging-runtime-ktx:2.6.0" implementation "androidx.paging:paging-compose:3.2.0-rc01"
・PagingSource
getRefreshKeyをnullにするとrefresh関数を呼ぶと初期化される
loadのprevKeyとnextKeyは読み込みに成功したときに次のページの場所を伝える
https://tech.pepabo.com/2021/10/18/android-paging3/
class PagingSource( private val api: API, ) : PagingSource<Int, Model>() { override fun getRefreshKey(state: PagingState<Int, Model>): Int? { return null } override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Model> { return try { val pager = params.key ?: 1 val response = api.exec(pager) LoadResult.Page( data = response, prevKey = (pager - 1).takeIf { key -> key > 0 }, nextKey = (pager + 1).takeIf { _ -> response.isNotEmpty() } ) } catch (e: Exception) { LoadResult.Error(e) } } }
・PagingSourceその2
ページングなしの場合は以下にする
LoadResult.Page( data = response, prevKey = null, nextKey = null )
・ViewModel
pagingSizeで一ページの数を渡す
val pager = Pager(PagingConfig(pageSize = 100)) { PagingSource(api) }.flow.cachedIn(viewModelScope)
・View
データをLazyColumnに渡すだけ
ページングとか先読みとかは勝手にやってくれる
すげー便利
https://proandroiddev.com/pagination-in-jetpack-compose-with-and-without-paging-3-e45473a352f4
val list = viewModel.pager.collectAsLazyPagingItems() LazyColumn { items( count = list.itemCount, key = list.itemKey { it }, contentType = list.itemContentType { "Model名" } ) { index -> val model = list[index] ?: return@items } }
・paging3の更新
https://zenn.dev/portinc/articles/understand_android_pager3
val list = viewModel.pager.collectAsLazyPagingItems() list.refresh()
・リスト更新時
更新したときにスクロール位置が自動で戻らないないので・・・
stateで上に戻しましょう
val listState = rememberLazyListState() LaunchedEffect(Unit) { listState.scrollToItem(0) } LazyColumn(state = listState) { //hogehoge }
・paging3のエラーハンドリング
https://zenn.dev/portinc/articles/understand_android_pager3
どこの読み込みかでエラーを見る場所が違うので注意
ページングの読み込み時はフッターにボタンつけたりするのはすごく楽
val refreshLoadState = list.loadState.refresh // 更新時 val prependLoadState = list.loadState.prepend // 前データ val appendLoadState = list.loadState.append // 追加時 //ロード中 refreshLoadState == LoadState.Loading //エラー refreshLoadState is LoadState.Error //読み込み終了 loadState == LoadState.NotLoading(true))
関連記事:
- AndroidのPagingのCodelabをやってみたので学んだことをまとめる
- Jetpack ComposeのCodelab 10〜15章で学んだことを書く
- Flutter Apprentice9章と10章で分からなかったことをまとめる