Slide 1

Slide 1 text

insertSeparatorsで ヘッダーや別のアイテム付きの ページングリストを実装する kako351 Android Advent Calendar 2023

Slide 2

Slide 2 text

自己紹介 kako351 / @kako_351 Androidエンジニア ● バイク(ハンターカブ) ● ギター ● コーヒー自宅焙煎 趣味

Slide 3

Slide 3 text

本日話す内容 ● Paging3の基本的な実装方法 ● LazyColumnの基本的な実装方法 ● LazyColumnのitemを利用する方法 話さないこと
 話すこと ● Paging3のinsertSeparatorsについて ● データの区別について ● LazyColumnとの組み合わせ

Slide 4

Slide 4 text

ページングリスト中にヘッダーや別のアイテムを表示 できるようになる 例えば、左の画面のように リストアイテム: レシピ ヘッダー: 件数やソート機能 (上の赤枠) 途中: 別のレシピ検索提案(下の赤枠) ゴール

Slide 5

Slide 5 text

まずはいつものようにPagingDataを作成します。 PagingData作成 val list = Pager( PagingConfig( pageSize = 10, initialLoadSize = 10 ) ){ pagingSource }.flow.cachedIn(viewModelScope)

Slide 6

Slide 6 text

リストアイテムと他のアイテムを区別 する 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 ): UiModel() }

Slide 7

Slide 7 text

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)

Slide 8

Slide 8 text

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)

Slide 9

Slide 9 text

insertSeparators https://developer.android.com/reference/kotlin/androidx/paging/PagingData#(androidx.paging.PagingData).insertSep arators(androidx.paging.TerminalSeparatorType,kotlin.coroutines.SuspendFunction2) TerminalSeparatorType セパレータを表示するタイミングを設定するモード。2つある。 ● FULLY_COMPLETE ○ PagingSourceとRemoteMediatorの両方がページネーションの終わりに達したときにセパ レーターを表示する ● SOURCE_COMPLETE ○ RemoteMediatorの状態に関係なく、PagingSourceがページネーションの最後に到達した時 点で、端末のセパレーター(ヘッダーとフッター)を表示する

Slide 10

Slide 10 text

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 で処理します。

Slide 11

Slide 11 text

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) } } } ところどころ雑なところはご了承ください......🙇

Slide 12

Slide 12 text

UIに表示する Paging3のSeparatorsを利用してリスト中にヘッダー や別のアイテムを挿入した画面が実装できました 🎉

Slide 13

Slide 13 text

まとめ ● リスト中に別のアイテム(セパレータ)を挿入するにはinsertSeparatorsを使う ● データを区別するには sealed classやsealed interface (interface)で可能 ● LazyColumn内でデータサブクラスごとに表示分けを行う

Slide 14

Slide 14 text

● データ ストリームを変換する 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 参考情報

Slide 15

Slide 15 text

ご静聴 ありがとう ございました 15 
 kako351