Tob*_* M. 8 android kotlin android-viewmodel android-jetpack-compose lazycolumn
我正在尝试 Android 的 Jetpack Compose。
\n对于简单的用例,一切都按预期工作,
\n但我在缺少更高级案例的重组方面遇到了一些麻烦。
我的型号:
\n我正在模拟一个原料存储系统,其中
\ndata class Ingredient(val name: String, @DrawableRes val iconResource: Int? = null)\nRun Code Online (Sandbox Code Playgroud)\ndata class StorageItem(val ingredient: Ingredient, var stock: Int)\nRun Code Online (Sandbox Code Playgroud)\n我的可组合项:
\n我的StorageUi可组合项应该列出所有存储项目
\n并显示成分的图标和名称以及库存。
\n对于这篇文章,我删除了所有不相关的修饰符和格式以简化可读性。
\n(请注意,我使用没有视图模型的第二个版本重载了 StorageScreen 可组合项,
\n是为了更轻松地进行测试并促进 Android Studio 中的预览功能。)
@Composable\n fun StorageScreen(viewModel: StorageViewModel) {\n StorageScreen(\n navController = navController,\n storageItems = viewModel.storageItems,\n onIngredientPurchased = viewModel::purchaseIngredient\n )\n }\n\n @Composable\n fun StorageScreen(storageItems: List<StorageItem>, onIngredientPurchased: (StorageItem) -> Unit) {\n Column {\n TitleBar(...)\n IngredientsList(storageItems, onIngredientPurchased)\n }\n }\n\n @Composable\n private fun IngredientsList(storageItems: List<StorageItem>, onIngredientPurchased: (StorageItem) -> Unit) {\n LazyColumn {\n items(storageItems) { storageItem ->\n IngredientCard(storageItem, onIngredientPurchased)\n }\n }\n }\n\n @Composable\n private fun IngredientCard(storageItem: StorageItem, onIngredientPurchased: (StorageItem) -> Unit) {\n Card(\n Modifier.clickable { onIngredientPurchased(storageItem) }\n ) {\n Row {\n ImageIcon(...)\n\n Text(storageItem.ingredient.name)\n\n Text("${storageItem.stock}x")\n }\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n我的视图模型:
\n在我的 ViewModel 中,我
\n class StorageViewModel : ViewModel() {\n\n var storageItems = mutableStateListOf<StorageItem>()\n private set\n\n fun purchaseIngredient(storageItem: StorageItem) {\n storageItem.stock += 1\n }\n\n }\nRun Code Online (Sandbox Code Playgroud)\n问题:更改原料库存时不会发生重组
\n我尝试更改事件处理程序以简单地从列表中删除点击的项目:
\n fun purchaseIngredient(storageItem: StorageItem) {\n storageItems.remove(storageItem)\n }\nRun Code Online (Sandbox Code Playgroud)\n然后瞧\xc3\xa0,UI 重新组合,点击的成分消失了。
\n我学到的是:
\n我想向你们学习的是:
\n如果列表中的任何元素更改其状态,我该怎么做才能实现重组?
仅当您更改列表本身时才会发生重组。你可以这样做。
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于这是一个非常常见的操作,因此您可以创建一个扩展函数以使其看起来更好一些。
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)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8191 次 |
| 最近记录: |