PagedListAdapter
を試していましたが、アダプターの位置を正しく復元する方法がわかりません。
最後の試みは、現在のリストからlastKey
を保存することでした。
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val lastKey = adapter.currentList?.lastKey as Int
outState.putInt("lastKey", lastKey)
}
しかし、アダプタを復元してlastKey
をPagedListBuilder
に渡すと、最後に見たものと表示されているものがかなり異なります。
val dataSourceFactory = dao.reportsDataSourceFactory()
val builder = RxPagedListBuilder(
dataSourceFactory,
PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setInitialLoadSizeHint(60)
.setPageSize(20)
.setPrefetchDistance(60)
.build()
)
.setInitialLoadKey(initialLoadKey)
.setBoundaryCallback(boundaryCallback)
ページ#4の中央 にいる場合、再開時に-アダプターは ページ#4の先頭 の位置にあります。理想的には、アダプターは最後に見たのとまったく同じ位置に復元する必要があります。
LayoutManagerの状態を保存するためのさまざまな試み
outState.putParcelable("layout_manager_state", recycler_view.layoutManager.onSaveInstanceState())
そしてそれを復元します
recycler_view.layoutManager.onRestoreInstanceState(it.getParcelable("layout_manager_state"))
惨めに失敗した。任意の提案を歓迎します:)
ついにそれを機能させることができました。
前提条件-PagedListAdapter
はnullプレースホルダーをサポートする必要があります! setEnablePlaceholders(true)
。続きを読む ここ
val dataSourceFactory = dao.reportsDataSourceFactory()
val builder = RxPagedListBuilder(
dataSourceFactory,
PagedList.Config.Builder()
.setEnablePlaceholders(true) //in my original implementation it was false
.setInitialLoadSizeHint(60)
.setPageSize(20)
.setPrefetchDistance(60)
.build()
)
通常どおり状態を保存します。
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val lastKey = adapter.currentList?.lastKey as Int
outState.putInt("lastKey", lastKey)
outState.putParcelable("layout_manager_state", recycler_view.layoutManager.onSaveInstanceState())
}
ただし、復元する場合-最初に状態を変数として保存し、リストをPagedListAdapter
に送信した後にのみ保存状態を復元します
private fun showReports(pagedList: PagedList<Report>?) {
adapter.submitList(pagedList)
lastLayoutManagerState?.let {
report_list.layoutManager.onRestoreInstanceState(lastLayoutManagerState)
lastLayoutManagerState = null
}
}
ここで、lastLayoutManagerState
は次のとおりです。
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = withViewModel(viewModelFactory) {
observe(reports, ::showReports)
}
report_list.adapter = adapter
lastLayoutManagerState = savedInstanceState?.getParcelable("layout_manager_state")
val lastKey = savedInstanceState?.getInt("lastKey")
viewModel.getReports(lastKey)
}
ああ、ViewHolder
をonBindViewHolder
にバインドするとき、アイテムがnullの場合はすぐに救済します。
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position) ?: return
...
}
アダプターのアイテム数が保存された状態のアイテム数と一致しないため、nullになります(ここで推測します)。そのため、一部の実験では、レイアウトが1ページで機能しているときに2ページ目でジャンプしていました。
手動で保存してからlastLayoutManagerState
を使用せずにこれにアプローチするより良い方法がある場合は、私に知らせてください。