简体   繁体   English

Android 使用 Jetpack Compose 无滚动地无限加载 Paging 3 库

[英]Android Paging 3 library loading infinitely without scroll with Jetpack Compose

I'm attempting to make a paged list of books using Jetpack Compose and Android's Paging 3 library.我正在尝试使用 Jetpack Compose 和 Android 的 Paging 3 库制作一个分页的图书列表。 I am able to make the paged list and get the data fine, but the load() function of my paging data source is being called infinitely, without me scrolling the screen.我能够制作分页列表并获得数据,但是我的分页数据源的load() function 被无限调用,而无需滚动屏幕。

My paging data source looks like this:我的分页数据源如下所示:

class GoogleBooksBookSource @Inject constructor(
    private val googleBooksRepository: GoogleBooksRepository,
    private val query: String
): PagingSource<Int, Book>() {

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Book> {
        val position = params.key ?: 0
        return try {
            val response = googleBooksRepository.searchForBookStatic(query, position)
            if (response is Result.Success) {
                LoadResult.Page(
                    data = response.data.items,
                    prevKey = if (position == 0) null else position - 1,
                    nextKey = if (response.data.totalItems == 0) null else position + 1
                )
            } else {
                LoadResult.Error(Exception("Error loading paged data"))
            }
        } catch (e: Exception) {
            Log.e("PagingError", e.message.toString())
            return LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Book>): Int? {
        return state.anchorPosition?.let { anchorPosition ->
            val anchorPage = state.closestPageToPosition(anchorPosition)
            anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
        }
    }
}

and this is the UI:这是用户界面:

Column() {
    // other stuff
    LazyColumn(
        modifier = Modifier.padding(horizontal = 24.dp),
        content = {
            for (i in 0 until searchResults.itemCount) {
                searchResults[i]?.let { book ->
                    item {
                        BookCard(
                            book = book,
                            navigateToBookDetail = { navigateToBookDetail(book.id) }
                        )
                    }
                }
            }
        }
    )
}

As far as I can tell, the data loads correctly and in the correct order, but when I log the API request URLs, it's making infinite calls with an increasing startIndex each time.据我所知,数据以正确的顺序正确加载,但是当我记录 API 请求 URL 时,它会进行无限调用,每次调用的startIndex都会增加。 That would be fine if I was scrolling, since Google Books searches often return thousands of results, but it does this even if I don't scroll the screen.如果我正在滚动,那会很好,因为 Google Books 搜索通常会返回数千个结果,但即使我不滚动屏幕,它也会这样做。

The issue here was the way I was creating elements in the LazyColumn - it natively supports LazyPagingItem but I wasn't using that.这里的问题是我在LazyColumn中创建元素的方式 - 它本身支持LazyPagingItem但我没有使用它。 Here is the working version:这是工作版本:

LazyColumn(
    modifier = Modifier.padding(horizontal = 24.dp),
    state = listState,
    content = {
        items(pagedSearchResults) { book ->
            book?.let {
                BookCard(
                    book = book,
                    navigateToBookDetail = { navigateToBookDetail(book.id) }
                )
            }
        }
    }
)

In your original example, you have to use peek to check for non-null and access the list as you do only inside item block, which is lazy.在您的原始示例中,您必须使用peek检查非空并访问列表,就像您只项目块内所做的那样,这是惰性的。 Otherwise the paging capabilities will be lost and it will load the entire dataset in one go.否则分页功能将丢失,它将在一个 go 中加载整个数据集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM