Android Compose LazyColumn IllegalArgumentException:密钥已被使用
Posted
技术标签:
【中文标题】Android Compose LazyColumn IllegalArgumentException:密钥已被使用【英文标题】:Android Compose LazyColumn IllegalArgumentException: Key was already used 【发布时间】:2021-12-18 22:31:47 【问题描述】:我不断收到 IllegalArgumentException: Key was already used。如果您使用的是 LazyColumn/Row,请确保为每个项目提供唯一的键。
我确信我的钥匙是独一无二的。这是我的示例代码:
@Composable
fun UiComponent()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
state = scrollState,
reverseLayout = true
)
items(
items = viewmodel.messages,
key = item -> item.hashcode() ,
itemContent = item: Entity ->
if (item.isDeleted)
//show deleted ui
else
//show messages
)
ViewModel
init
observeDataFromDB()
private val _messages: MutableList<Entity> = mutableStateListOf()
val messages: List<Entity> = _messages
fun observeDataFromDB()
viewModelScope.launch
repo.getData().collect
_messages.apply
addNewItem(it)
//extensions
fun MutableList<Entity>.addNewItem(entity: Entity)
if (this.size >= MAX_SIZE)
removeLast()
Log("existing $this.toList().map "$it.hashCode()" ")
Log("adding new $entity.hashCode()")
this.add(0, entity)
//id is unique
data class Entity(id:String, isDeleted: Boolean, message: String)
我也尝试从我的 Viewmodel(StateFlow<List<Entity>
) 中提供一个 observable,但我得到了同样的错误。还尝试将id
设置为键。
通常在快速添加项目时遇到此问题。例如,用户在短时间内发送多条垃圾邮件。
【问题讨论】:
请添加数据类Entity
代码。
究竟什么时候发生错误?当您启动应用程序时,或者当您实际滚动列时?
当一个项目被添加到惰性列时
即使 ID 是唯一的,您仍然可能有重复的数据,这使得 LazyColum “认为” ID 不是唯一的。所以检查重复并在那里解决问题。导致问题的快速消息表明它可能是这种情况。
【参考方案1】:
如果您的任何消息相同,您最终会得到相同的哈希码值,这将产生错误。为避免这种情况,如果您的消息没有 id,请使用 itemsIndexed
而不是仅使用 items
并将索引指定为键:
@Composable
fun UiComponent()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
state = scrollState,
reverseLayout = true
)
items(
items = viewmodel.messages,
key = item -> item.id ,
itemContent = item: Entity ->
if (item.isDeleted)
//show deleted ui
else
//show messages
)
【讨论】:
但是 id 永远是唯一的。data class Entity(val id: String, isDeleted: Boolean, val message: String)
。另外,如果我使用索引,如果Entity
中的isDeleted
发生变化,LazyColumn
中的任何行都会被重新组合吗?
您没有使用 id。您正在将密钥设置为 item.hashcode()。我更新了我的代码并将 item.hashcode 替换为 item.id。
还是一样的错误:(
在调用 LazyColumn 之前将所有项目的 id 打印到 Log 并检查它们是否都是唯一的。我很确定您的列表中有重复的项目。以上是关于Android Compose LazyColumn IllegalArgumentException:密钥已被使用的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack Compose学习—— Jetpack compose基础布局
Android Jetpack Compose学习—— Jetpack compose基础布局