如何在Jetpack Compose的LazyColumn/LazyRow中获取列表项的Key?
解决Jetpack Compose LazyColumn中获取项Key的问题
目前Compose并没有提供直接获取Lazy项已分配Key的API,不过可以通过以下几种简单方式实现需求:
直接复用Key生成逻辑
既然Key是你自己用index和ingredient.url生成的,在item的lambda里直接重新生成一遍就行,逻辑完全一致,不会有问题:itemsIndexed( items = food.ingredients, key = { index, ingredient -> "${index}:${ingredient.url}" } ) { index, ingredient -> val itemKey = "${index}:${ingredient.url}" // 直接生成相同的Key Text(text = ingredient.name) // 这里就可以使用itemKey了 }抽离Key生成函数(避免重复代码)
如果担心重复写生成逻辑容易出错,可以把Key的生成逻辑抽成单独的函数,两处调用同一个函数:// 抽离的生成函数 private fun getIngredientKey(index: Int, ingredient: Ingredient): String { return "${index}:${ingredient.url}" } // LazyColumn中的使用 LazyColumn(content = { foodList.forEach { food -> item { Text(text = food.name) } itemsIndexed( items = food.ingredients, key = { index, ingredient -> getIngredientKey(index, ingredient) } ) { index, ingredient -> val itemKey = getIngredientKey(index, ingredient) Text(text = ingredient.name) // 使用itemKey } } })封装数据与Key(适合复杂场景)
如果Key的生成逻辑比较复杂,或者不想每次都计算,可以提前把食材和对应的Key包装成一个数据类,再传入items:// 自定义包装类 data class IngredientWithKey(val ingredient: Ingredient, val key: String) // LazyColumn中的使用 LazyColumn(content = { foodList.forEach { food -> item { Text(text = food.name) } // 提前生成带Key的列表 val ingredientsWithKeys = food.ingredients.mapIndexed { index, ingredient -> IngredientWithKey(ingredient, getIngredientKey(index, ingredient)) } items( items = ingredientsWithKeys, key = { it.key } ) { item -> Text(text = item.ingredient.name) // 直接使用item.key } } })
本质上,因为Compose的Lazy组件只把Key用作重组标识,并没有将其暴露给项的内容lambda,所以只能通过复用生成逻辑或者提前绑定的方式拿到Key。
内容的提问来源于stack exchange,提问作者Mostafa Arian Nejad
相关产品推荐
相关产品推荐

