我正在试验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组合应该列出所有存储项
并显示成分的图标和名称,以及库存。
对于这篇文章,我删除了所有不相关的修饰符和格式以简化易读性。
(请注意,我使用没有视图模型
的第二个版本重载了我的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")
}
}
}
我的视图模型:
在我的视图模型中,我
class StorageViewModel : ViewModel() {
var storageItems = mutableStateListOf<StorageItem>()
private set
fun purchaseIngredient(storageItem: StorageItem) {
storageItem.stock += 1
}
}
问题是:当改变一种配料的库存时,没有重组发生
我尝试更改事件处理程序,以简单地从列表中删除点击的项:
fun purchaseIngredient(storageItem: StorageItem) {
storageItems.remove(storageItem)
}
瞧,用户界面重新组合,被点击的成分消失了。
我学到了什么:
我想向你们学习的是:
如果列表中的任何元素更改其状态,我可以做些什么来实现重组?
仅当您更改列表本身时,才会进行重新组合。你可以这样做。
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)
}
}
我正在尝试使用RxAndroid Flowable的订阅者更新LazyColumn项目。我用于图像列表的状态变量简称为“列表” 这是我的懒惰列代码: 例如,如果我运行此测试协程,列表将更新并显示正确数量的测试图像: 但是,如果我使用对Flowable的订阅尝试相同的方法,它会更新变量值,但不会触发重新编译。这是我的代码: 我如何处理一个可组合的流动?
假设我有一个由n个字符串列表组成的列表: result->包含所有输出列表(所有组合) current->是当前的组合 用上述相同示例调用此函数时的输出:
我想要一个列表,它是列表元素列表的组合,例如:我的输入 输出应该是 非常感谢您的帮助。
我的模式是: 我的xml将是: 案例1。 或案例2。 对于案例2,没有问题。但对于案例1,我得到了以下错误: 如何修改wsdl,使其同时接受案例1和案例2?请帮忙。
我有客户对象的列表。我想迭代列表并按1递增顺序。 我尝试了每个列表,但在这里我必须创建新列表并在其中添加值。 有没有更好的方法?我尝试使用streams,但它只是映射订单
通过列表综合,可以从一个已有的列表导出一个新的列表。例如,你有一个数的列表,而你想要得到一个对应的列表,使其中所有大于2的数都是原来的2倍。对于这种应用,列表综合是最理想的方法。 使用列表综合 例15.1 使用列表综合 #!/usr/bin/python # Filename: list_comprehension.py listone = [2,3,4] listtwo = [2*iforiin