こんにちは、 id:numanuma08 です。最近調査、修正したPagingを使った画面でスクロールが重たくなり操作不能になるバグとその対策を紹介します。
当該画面は次のようにNestedScrollView内部に2つのRecyclerViewが配置されていました。
この状態でPagingを使うとページネーションされたすべてのデータを読み込み、表示しようとしてしまいます。そのためRecyclerViewの再描画が大量に発生して、スクロールが重たくなる不具合が発生していました。
NestedScrollView内に配置されたRecyclerViewは内部に表示するコンテンツの量に応じてView自体の高さが決定されます。そして、Pagingは一番最後の要素が描画されると次のページの要素を取得しに行きます。この2つの動作が組み合わさると、ページネーションしているのに画面を開いた瞬間ページのいちばん最後までデータを取得して表示を試みてしまいます。その結果、アプリのスクロール動作が遅くなります。
どうすればいいのか
ConcatAdapterを使って単一のRecyclerViewで画面を構成するといいでしょう。
NestedScrollViewも利用せず、RecyclerViewのみで画面全体を構成します。ConcatAdapterはコンストラクタやプロパティからアダプター自体を追加可能です。複数RecyclerViewを使って画面を構成していた場合、2つ以上のRecyclerView.Adapterが存在するためそれらをのリストをConcatAdapterにセットすればOKです。
val usersAdapter = UsersAdapter() val classesAdapter = ClassesAdapter() val adapter = ConcatAdapter( usersAdapter, classesAdapter ) binding.recyclerView.adapter = adapter
データの更新は元となったアダプターに対して行います。
observe(viewModel.users) { usersAdapter.submitList(it) }
まとめ
複数のRecyclerViewをNestedScrollView内に配置したときにPagingの挙動がおかしくなる事例と対策を紹介しました。ページネーションを使った画面で異常にスクロールにもたつきがある報告が上がってきたら、このあたりを調査してみると良いかもしれません。