Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Paging3のSeparatorsを使って LazyColumnにヘッダーや 別のアイテムを...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for kako351 kako351
December 16, 2023

Paging3のSeparatorsを使って LazyColumnにヘッダーや 別のアイテムを挿入する

このスライドは Android Advent Calendar 2023 16日目のスライドです。

https://qiita.com/advent-calendar/2023/android

Avatar for kako351

kako351

December 16, 2023
Tweet

More Decks by kako351

Other Decks in Technology

Transcript

  1. リストアイテムと他のアイテムを区別 する sealed class UiModel { data class Recipe( val

    index: Int, val title: String ): UiModel() data class Header( val totalCount: Int ): UiModel() data class RelatedSearch( val keywords: List<String> ): UiModel() }
  2. PagingDataのデータストリームを変換 する pager.flow.map { it.insertSeparators { before, after -> when

    { before == null -> UiModel.Header(999) after?.index == 2 -> UiModel.RelatedSearch(/* todo list */) else -> null } } }.cachedIn(viewModelScope)
  3. insertSeparators 引数は以下の2つを持っています。 • terminalSeparatorType: TerminalSeparatorType • generator: suspend (before: T?,

    after: T?) -> R? generator内で生成したセパレータと元の要素を含むPagingDataを返します。 https://developer.android.com/reference/kotlin/androidx/paging/PagingData#(androidx.paging.PagingData).insertSep arators(androidx.paging.TerminalSeparatorType,kotlin.coroutines.SuspendFunction2)
  4. insertSeparators https://developer.android.com/reference/kotlin/androidx/paging/PagingData#(androidx.paging.PagingData).insertSep arators(androidx.paging.TerminalSeparatorType,kotlin.coroutines.SuspendFunction2) generator: suspend (before: T?, after: T?) ->

    R? 前後の要素を受け取ります。終端の場合はbefore、afterはそれぞれ nullになりま す。 リストが完全に空の場合はbefore、afterがともにnullになります。 つまり ヘッダーを追加したい場合は before == null で処理します。
  5. LazyColumnにセパレータ付きのPagingDataを渡します。 paging-composeを利用します(※alpha版です 2023/07/21時点) UIに表示する val list = viewModel. list.collectAsLazyPagingItems ()

    LazyColumn { items(count = list.itemCount, key = { it }) { index -> val item = list[index] ?: return@items when(item) { is UiModel.Header -> HeaderItem(item) is UiModel.Recipe -> RecipeItem(item) is UiModel.RelatedSearch -> RelatedSearchItems (item) } } } ところどころ雑なところはご了承ください......🙇
  6. • データ ストリームを変換する https://developer.android.com/topic/libraries/architecture/paging/v3-t ransform?hl=ja#convert-ui-model • Paging: Getting fancy with

    transformations, separators, headers, footers and search - MAD Skills https://www.youtube.com/watch?v=ZARz0pjm5YM 参考情報