我正在尝试使用 Android 的 Jetpack Compose。
对于简单的用例,一切都按预期工作,
但我有一些 缺少重组的问题对于更高级的案例。
这是我在 stackoverflow 上的第一篇文章。我希望我能很好地描述我的问题以获得一些帮助。 ;)
我的模特 :
我正在模拟 存储 成分系统,其中
data class Ingredient(val name: String, @DrawableRes val iconResource: Int? = null)
data class StorageItem(val ingredient: Ingredient, var stock: Int)
我的可组合物 :我的 的组合StorageUi 应该列出所有存储项目
并显示成分以及库存的图标和名称。
对于这篇文章,我去掉了所有不相关的修饰符和格式以简化可读性。
(请注意,我用没有 View 模型的第二个版本重载了我的 StorageScreen 组合
以便于测试并促进 Android Studio 中的预览功能。)
@Composable
fun StorageScreen(viewModel: StorageViewModel) {
StorageScreen(
navController = navController,
storageItems = viewModel.storageItems,
onIngredientPurchased = viewModel::purchaseIngredient
)
}
@Composable
fun StorageScreen(storageItems: List<StorageItem>, onIngredientPurchased: (StorageItem) -> Unit) {
Column {
TitleBar(...)
IngredientsList(storageItems, onIngredientPurchased)
}
}
@Composable
private fun IngredientsList(storageItems: List<StorageItem>, onIngredientPurchased: (StorageItem) -> Unit) {
LazyColumn {
items(storageItems) { storageItem ->
IngredientCard(storageItem, onIngredientPurchased)
}
}
}
@Composable
private fun IngredientCard(storageItem: StorageItem, onIngredientPurchased: (StorageItem) -> Unit) {
Card(
Modifier.clickable { onIngredientPurchased(storageItem) }
) {
Row {
ImageIcon(...)
Text(storageItem.ingredient.name)
Text("${storageItem.stock}x")
}
}
}
我的 View 型号:在我的 ViewModel 中,我
class StorageViewModel : ViewModel() {
var storageItems = mutableStateListOf<StorageItem>()
private set
fun purchaseIngredient(storageItem: StorageItem) {
storageItem.stock += 1
}
}
问题:更改成分的库存时不会发生重组我尝试更改事件处理程序以简单地从列表中删除被点击的项目:
fun purchaseIngredient(storageItem: StorageItem) {
storageItems.remove(storageItem)
}
瞧,UI 重新组合,轻拍的成分消失了。我学到了什么:
我想向你们学习:
最佳答案
What can I do to achieve a recomposition, if any element within the list changes its state?
仅当您更改列表本身时才会发生重组。你可以这样做。
class StorageViewModel : ViewModel() {
var storageItems by mutableStateOf(emptyList<StorageItem>())
private set
fun purchaseIngredient(storageItem: StorageItem) {
storageItems = storageItems.map { item ->
if(item == storageItem)
item.copy(stock = item.stock + 1)
else
item
}
}
}
由于这是一个非常常见的操作,因此您可以创建一个扩展函数以使其看起来更好一些。fun <T> List<T>.updateElement(predicate: (T) -> Boolean, transform: (T) -> T): List<T> {
return map { if (predicate(it)) transform(it) else it }
}
fun purchaseIngredient(storageItem: StorageItem) {
storageItems = storageItems.updateElement({it == storageItem}) {
it.copy(stock = it.stock + 1)
}
}
关于android - 更新列表元素内容时 Jetpack Compose : No recomposition happening,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69711167/