我使用 Android Jetpack Paging3 库进行分页,我遵循了 google code lab 和一些媒体博客以供引用。我已经按照他们的建议实现了分页,但它不起作用,viewmodel 总是返回 null 值。当我调试应用程序时,我知道 PageDataSource 没有调用。我不明白我按照文章关注的问题在哪里。以下是我的项目的代码 fragment 。
我在 RepositoryImpl 类中调用 Pager 的代码。
override suspend fun getSearchResult(searchKey: String): LiveData<PagingData<MyDataModel>> {
return Pager(
config = PagingConfig(NETWORK_PAGE_SIZE, enablePlaceholders = false),
pagingSourceFactory = {
MyPageDataSource(searchKey)
}).liveData
}
这是我的 View 模型类代码
viewModelScope.launch{
searchResult.value = Resource.loading(null)
val response = repo.getSearchResult(searchKey)
searchResult.value = Resource.success(response.value)
}
这是 MyPageDataSource 类
override fun getRefreshKey(state: PagingState<Int, MyDataModel>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyDataModel> {
// Start refresh at position 1 if undefined.
val page = params.key ?: INITIAL_LOAD_SIZE
val offset = params.loadSize
return try {
val response = searchRequest(searchQuery, page, offset) // its just api calling function which get result from API.
val nextKey: Int?
when (response) {
is SearchResult.Success -> {
nextKey = if (response.result.searchRes.isEmpty()) {
null
} else {
// initial load size = 3 * NETWORK_PAGE_SIZE
// ensure we're not requesting duplicating items, at the 2nd request
page + (params.loadSize / NETWORK_PAGE_SIZE)
}
LoadResult.Page(
data = response.result.searchRes,
prevKey = if (page == INITIAL_LOAD_SIZE) null else page - 1,// Only paging forward.
// assume that if a full page is not loaded, that means the end of the data
nextKey = nextKey
)
}
is SearchResult.NoResultFound -> {
nextKey = null
LoadResult.Page(
data = emptyList(),
prevKey = if (page == INITIAL_LOAD_SIZE) null else page - 1,// Only paging forward.
// assume that if a full page is not loaded, that means the end of the data
nextKey = nextKey
)
}
is SearchResult.ServerError -> {
val exception = Exception(response.message)
LoadResult.Error(exception)
}
}
} catch (e: Exception) {
e.printStackTrace()
LoadResult.Error(e)
}
}
最佳答案
我尝试了不同的方法来进行分页,最终通过使用函数返回类型作为LiveData来实现结果。在加载函数触发之后,一切就都解决了。
以下是 ViewModel 代码
suspend fun getSearchResult(searchKey:String):LiveData<PagingData<MyDataModel>> =repo.getSearchResult(searchKey)
在 fragment 中我可以像这样访问它
lifecycleScope.launch { viewmodel.getSearchResult(searchKey)..observe(viewLifecycleOwner) {
result -> //TODO}
我不知道为什么当我使用livedata变量访问时它不起作用。如果还有其他解决方案请留言。
关于Android Paging3 不调用 PageDataSource 并且始终将实时数据获取为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74235511/