Jetpack Compose Paging - 使用 key 和 contentType

Pet*_*cek 4 android android-paging android-jetpack-compose android-paging-3

因此,在我的应用程序中,我正在使用 Compose Paging,但遇到了一个问题,我不确定如何正确处理。我来描述一下这个问题:

在我的分页列表中,我显示两种类型的项目:标题和实际数据单元格。我从 API 获取这些数据单元格的数据,并使用 insertSeparators 方法在它们之间插入标题。

我通过使用密封类来区分标题和单元格数据对象:

sealed class PagingModel {
    data class Header(@StringRes val label: Int) : PagingModel()
    data class CellData(val data: DataResponse) : PagingModel()
} 
Run Code Online (Sandbox Code Playgroud)

因此,在分页源中,我将 api 结果映射到PagingModel.CellDatainsertSeparators 中,并在 insertSeparators 中添加PagingModel.Header一些之前/之后的逻辑。

现在,说到问题。我希望分页列表尽可能高效,因此我想在 LazyColumn 中使用 key 和 contentType 参数。这是一个代码片段:

items(
    count = lazyPagingItems.itemCount,
    key = lazyPagingItems.itemKey { **What do I put here when PagingData.Header has no key** },
    contentType = lazyPagingItems.itemContentType {**should it just be "it" ?** }
  ) { index -> ...}
Run Code Online (Sandbox Code Playgroud)

我将有关 key 和 contentType 的问题添加到这些 lambda 括号中。我最感兴趣的是关键参数,我尝试了这样的事情:

sealed class PagingModel {
    data class Header(@StringRes val label: Int) : PagingModel()
    data class CellData(val data: DataResponse) : PagingModel()
} 
Run Code Online (Sandbox Code Playgroud)

但我不知道要在 else 块中放入什么,当我省略它时,它会抛出一个预期的错误,即我不能使用 Unit 作为键。

这可行吗?任何帮助都感激不尽。谢谢!

Jan*_*ína 5

是的,这绝对是可行的。
对于密钥,label如果您只有唯一的标签,则可以使用 。为了避免它偶然与单元 ID 冲突,您可以在其前面加上“header”或其他内容:

key = lazyPagingItems.itemKey {
    when (it) {
        is Header -> "header_${it.label}"
        is CellData -> "cell_${it.id}"
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您有多个具有相同标签的标头,您可以为它们创建一些 id 并将其用作键:

data class Header(
    @StringRes val label: Int,
    val id: String = UUID.randomUUID().toString(),
) : PagingModel()
Run Code Online (Sandbox Code Playgroud)

对于contentType,它可以是任何东西。重要的是,具有相似布局的项目的内容类型是相等的,而具有不同布局的项目的内容类型是不相等的。
在您的情况下,您只有两种布局类型,因此您可以简单地执行以下操作:

contentType = lazyPagingItems.itemContentType { it is Header }
Run Code Online (Sandbox Code Playgroud)

with that, Header has contentType == true and Cell has contentType == false. That works. If you have more then two types, you can use integers. Or, if you want something more fancy, you can create an enum:

enum class MyListContentType { Header, Cell, ... }

contentType = lazyPagingItems.itemContentType {
    when (it) {
        is Header -> MyListContentType.Header
        is CellData -> MyListContentType.Cell
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 哇,非常感谢您的冗长回复,而且您还设法为我清除了 contentType,我不太确定该怎么做。再次非常感谢! (2认同)