恢复活动时恢复PagedListAdapter位置

Mar*_*kus 12 android android-paging

我一直在试验,PagedListAdapter无法弄清楚如何正确恢复适配器位置.

最后一次尝试是lastKey从当前列表中保存.

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)

    val lastKey = adapter.currentList?.lastKey as Int

    outState.putInt("lastKey", lastKey)
}
Run Code Online (Sandbox Code Playgroud)

但是当恢复我的适配器并传递lastKeyPagedListBuilder我上次看到的内容以及显示的内容时,相当不同.

    val dataSourceFactory = dao.reportsDataSourceFactory()
    val builder = RxPagedListBuilder(
        dataSourceFactory,
        PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setInitialLoadSizeHint(60)
            .setPageSize(20)
            .setPrefetchDistance(60)
            .build()
    )
        .setInitialLoadKey(initialLoadKey)
        .setBoundaryCallback(boundaryCallback)
Run Code Online (Sandbox Code Playgroud)

如果我在恢复时位于第4页中间位置 - 适配器将位于第4页开头的位置.理想情况下,适配器应该恢复到与上次看到的完全相同的位置.

各种尝试保存LayoutManager状态

outState.putParcelable("layout_manager_state", recycler_view.layoutManager.onSaveInstanceState()) 
Run Code Online (Sandbox Code Playgroud)

然后恢复它

recycler_view.layoutManager.onRestoreInstanceState(it.getParcelable("layout_manager_state"))
Run Code Online (Sandbox Code Playgroud)

悲惨地失败了.欢迎任何建议:)

Mar*_*kus 8

终于设法让它运作起来.

前提条件 - 您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()
    )
Run Code Online (Sandbox Code Playgroud)

像往常一样保存状态:

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())
}
Run Code Online (Sandbox Code Playgroud)

但是在恢复时 - 首先将状态保存为变量,并仅在将列表提交到后恢复已保存的状态PagedListAdapter

private fun showReports(pagedList: PagedList<Report>?) {
    adapter.submitList(pagedList)

    lastLayoutManagerState?.let {
        report_list.layoutManager.onRestoreInstanceState(lastLayoutManagerState)
        lastLayoutManagerState = null
    }
}
Run Code Online (Sandbox Code Playgroud)

在哪里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)
}
Run Code Online (Sandbox Code Playgroud)

哦,当我绑定时ViewHolder,onBindViewHolder如果item为null ,我就快速拯救.

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val item = getItem(position) ?: return
    ... 
}
Run Code Online (Sandbox Code Playgroud)

因为它将为null,否则适配器项目计数将与保存的状态项目计数(此处猜测)不匹配,这就是为什么在我的一些实验中,布局在页面2上跳转,而它在第1页上工作.

如果有更好的方法如何处理这个没有手动存储然后使用lastLayoutManagerState- 让我知道.