7

我有一个应用程序,它从 API 中获取158 个项目的列表,将其存储在 Room 中,并将其显示给用户。RoomDB 是事实的来源。

这是从数据库获取结果的 ViewModel 上的代码:

private val pagingConfig =
    PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 300)

fun getList(filters: Filters): Flow<PagingData<Character>> {
    return Pager(pagingConfig) {
        repository.getCharacters(filters)
    }.flow.map {
        it.asDomainModel()
    }
}

这是填充适配器的片段上的代码:

private fun fetchData(filters: Filters) {
    lifecycleScope.launch {
        charactersViewModel.getList(filters).collectLatest { pagedList ->
            characterAdapter.submitData(pagedList)
        }
    }
}

当前行为:

  • 当我的第 60 项之后发生配置更改时,滚动位置丢失,我发现将我的pagingConfig上的pageSize20增加到55,它解决了这个问题。

我已经尝试过的:

由于我是异步获取数据,因此我尝试使用本文中的这段代码防止在适配器为空时加载数据。但它没有用

characterAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY

我期望达到的目标:

能够滚动到列表底部并在不丢失滚动位置的情况下进行配置更改“而无需在列表变大时增加我的pageSize

https://github.com/doilio/DC-Characters

4

4 回答 4

3

不要从您的方法中返回Flow<PagingData>evertime的新实例。getList

做这样的事情:

class YourViewModel: ViewModel() {
   private mPagingData = Flow<PagingData<Character>>? = null;

   fun getList(filters: Filters): Flow<PagingData<Character>> {
      if(mPagingData != null) return mPagingData; //This is important
      else
         mPagingData = Pager(pagingConfig) {
              repository.getCharacters(filters)
         }.flow.map {
              it.asDomainModel()
         }
      return mPagingData;
   }
}

除此之外,请确保在onCreate片段中初始化适配器。

于 2021-08-19T09:34:20.273 回答
1

您正在寻找的方法是PagingSource.getRefreshKey(). 它给出了先前的状态 a PagingState,它具有字段PagingState.anchorPosition,最后访问的索引(包括占位符)。

https://developer.android.com/topic/libraries/architecture/paging/v3-network-db#refresh-in-place

编辑:我现在看到您正在使用 Room 的实现。实际上存在一些与 Remote REFRESH 及其 getRefreshKey 实现相关的错误,应该在下一个版本 (alpha07) 中解决。请参阅https://issuetracker.google.com/issues/167260236

于 2020-07-18T15:40:34.810 回答
0

PagingDataAdapter有一个名为loadStateFlow的属性,其中包含内部已处理数据的状态。

你可以这样尝试:

lifecycleScope.launchWhenCreated {
        adapter.loadStateFlow.map { it.refresh }
            .distinctUntilChanged()
            .collect {
                if (it is LoadState.NotLoading) {
                    // reset to position you wanted
                }
            }
    }

LoadState.NotLoading是 loadStateFlow 的具体状态对应处理数据完成的状态。

LoadState.NotLoading

于 2021-12-28T13:32:33.743 回答
0

有同样的问题。在我的情况下,我将 PagingConfig enablePlaceholders 更改为 true,并将 initialLoadSize 设置为可除以 pageSize(例如 pageSize=10,initialLoadSize = 20)。

于 2020-08-30T19:45:01.640 回答