0
0

More than 3 years have passed since last update.

LiveDataを使わずにRxでPagingする

Last updated at Posted at 2020-01-08

みなさんPaging使ってますか?

公式ドキュメントを見ると、LiveDataを使わずにRxJava2を使用しても良いということだったのですが、いまいちどのように実装するのかがよくわからず試行錯誤した結果を書き残したいと思います。

前提

  • 以下の条件の方々を読者と仮定します
    • AAC Pagingがどのようなものか大体わかる
    • これからPagingを導入しようと思っている
    • LiveDataは導入していない

やること

AndroidXの場合

DataSourceFactory#toObservableでPagedListのObservableを作成する
or
LivePagedListBuilderを使うかわりにRxPagedListBuilderを使う

AndroidXじゃない場合

LivePagedListBuilderを使うかわりにRxPagedListBuilderを使う

まず、PagingのRxサポートはオプショナルなのでbuild.gradleに追加で記述が必要になります。
また、AndroidXでtoObservableしたい場合はktxも入れる必要があります


implementation "androidx.paging:paging-runtime:$paging_version"
implementation "androidx.paging:paging-runtime-ktx:$paging_version"
implementation "androidx.paging:paging-rxjava2:$paging_version"
implementation "androidx.paging:paging-rxjava2-ktx:$paging_version"   

AndroidXでtoObservableを使う場合は公式のドキュメントを見れば困ることは特にないと思います。
RxPagedListBuilderを使用する場合はFactoryクラスとConfigをBuilderに突っ込めばOKです


    lateinit var pagedList: Observable<PagedList<YourObj>>

    fun setupPage() {
        val config = PagedList.Config.Builder()
                .setInitialLoadSizeHint(YOUR_LOAD_SIZE)
                .setPageSize(YOUR_PAGE_SIZE)
                .setEnablePlaceholders(false)
                .build()
        //DataSource.Factoryの継承クラス
        val factory = YourFactory() 
        pagedList = RxPagedListBuilder(factory, config)
                .buildObservable()
    }

こうしてできたObservableをサブスクライブして、onNextに入ってくるPagedListをsubmitしていくという寸法です。

ハマったところ

NestedScrollView内のRecyclerViewをPagingするとバグる

私がやった時はヘッダーが必要だったので、以下のようなレイアウト構成で実装しようと思っていました

  • NestedScrollView
    • LinerLayout
      • TextView < これがヘッダー
      • RecyclerView < ここでPaging

ところが、このようにすると一度に全てのデータを読み込み、表示しようとしてしまうので動作が極端に重くなります。
PagingのSampleに同様のissueが建てられていましたが、どうも解決しなさそうです(RecyclerViewの仕様?)
うまくPagingを動作させつつスクロール部分の表示を要素にとって変えたい時には、サボらずに一つのRecyclerViewでViewHolderを切り替えて表示を出し分ける必要があるようです。

RxPagedListBuilderのSchedulerの扱い

RxPagedListBuilderで作成したObservableは特別subscribeOnobserveOnを記述する必要がありません。(別途設定は可能 ドキュメント参照)
気を付けなければならないのはDataSourceがBuilderで設定したSchedulerのスレッド配下であるということです。
私の場合、DataSource内で通信して追加データを取得する際に、RetrofitでSingleを返すようにしていましたが、ワーカースレッドの入れ子状態になるために正常に結果が返ってこない自体に陥りました。
そのため、DataSource内の通信ではCallを使用することで回避しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0