Android Paging 3.0 加载方法无效

Android Paging 3.0 load method not working

我正在尝试实现 android 分页 3.0 库,但我遇到了 .load 方法不起作用的问题,起初我以为适配器 submitData 或 layoutManager 不起作用,因为我确实得到了响应来自 LoadResult.Page,但现在进一步观察时,它有点停止工作了

这是我的代码

1- 片段

private fun initAdapter() {
    searchAdapter = SearchItemsAdapter {
        //item clicked
    }
    val gridLayoutManager = GridLayoutManager(requireContext(), 2)
    binding?.layoutManager = gridLayoutManager
    binding?.searchAdapter = searchAdapter
}
private fun startSearch() {
    searchJob?.cancel()
    searchJob = viewLifecycleOwner.lifecycleScope.launch {
        searchViewModel?.getSearchResults("phone")?.collectLatest {
            searchAdapter?.submitData(it)
        }
    }
}

2- ViewModel

fun getSearchResults(query: String): Flow<PagingData<ItemModel>> {
    val lastResult = currentSearchResult
    if (query == currentQueryValue && lastResult != null) {
        return lastResult
    }
    currentQueryValue = query
    val newResult: Flow<PagingData<ItemModel>> = searchRepository.getSearchResults(query)
        .cachedIn(viewModelScope)
    currentSearchResult = newResult
    return newResult
}

3- SearchRepository

fun getSearchResults(query: String): Flow<PagingData<ItemModel>> {
    return Pager(
        config = PagingConfig(
            pageSize = 10
        ),
        pagingSourceFactory = { SearchPagingSource(client, query) }
    ).flow
}

4- PagingSource

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ItemModel> {
    val position: Int = params.key ?: 1
    return try {
        val response: SearchResponse = service.getSearchResult(query, position)
        val items = response.metadata.results
        val nextKey = if (items.isEmpty()) {
            null
        } else {
            position + 1
        }
        LoadResult.Page(
            data = items,
            prevKey = if (position == 1) null else position - 1,
            nextKey = nextKey
        )
    } catch (exception: IOException) {
        return LoadResult.Error(exception)
    } catch (exception: HttpException) {
        return LoadResult.Error(exception)
    }
}

5- 适配器

override fun onBindViewHolder(holder: SearchItemsViewHolder, position: Int) {
    val item = getItem(position)
    if (item != null) {
        holder.binding.item = item
        holder.itemView.setOnClickListener {
            itemClickCallback(item)
        }
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchItemsViewHolder {
    val layoutInflater = LayoutInflater.from(parent.context)
    val binding = SearchItemLayoutBinding.inflate(layoutInflater, parent, false)
    return SearchItemsViewHolder(binding)
}

companion object {
    private val diffCallBack = object : DiffUtil.ItemCallback<ItemModel>() {
        override fun areItemsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean =
            oldItem.id == newItem.id

        override fun areContentsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean =
            oldItem == newItem
    }
}

我发现了我遇到的问题

1- 我没有从片段的 onViewCreated 方法调用 startSearch 方法,这对 API 调用没有帮助

2- XML 中的 recyclerView 具有 wrap_content 而不是 0dp 作为高度

对我来说,我的数据class是

data class Score(
    val userId: String,
    val username: String,
    val avatarPath: String,
    val score: Long,
)

我改成了

data class Score(
    var userId: String? = null,
    var username: String? = null,
    var avatarPath: String? = null,
    var score: Long? = null,
)

现在可以使用了!!