下面是一个简单的购物车实现,其中如果单击列表项,则 qty 的值应增加 1...
但不知何故,ViewModel 中的值正在发生变化,但未反射(reflect)在 UI 中(未使用新的数量值重新组合)
我认为问题出在这部分:
LazyColumn {items(cartInfo.value!!.cartItems){...}
如 cartItems
不是直接的状态值,这就是为什么不触发 LazyColumn UI 的重组的原因。
但无法解决这个问题 mutableStateOf<CartInfo?>
已修复,我不希望 MutableList<CartItem>
有单独的状态
data class User(var id: String, var name: String)
data class Product(var id: String, var name: String)
data class CartItem(var product: Product, var qty: Int)
data class CartInfo(val userid: String, val cartItems: MutableList<CartItem>)
val user = User("1", "A")
val item1 = CartItem(Product("1", "iPhone"), 1)
val item2 = CartItem(Product("2", "Xbox"), 1)
val cart = CartInfo(user.id, mutableListOf(item1, item2))
class MainViewModel : ViewModel() {
private val _cartInfo = mutableStateOf<CartInfo?>(null)
val cartInfo: State<CartInfo?> = _cartInfo
init {
_cartInfo.value = cart
}
fun increaseQty(product: Product, user: User) {
viewModelScope.launch {
var cartInfo = cartInfo.value
if (user.id == cartInfo?.userid) {
var cartItems = cartInfo.cartItems.map {
if (it.product.id == product.id) {
it.qty += 1
it
} else
it
}
_cartInfo.value = cartInfo.copy(cartItems = cartItems as MutableList<CartItem>)
}
// Log.d("debug", "viewmodel: ${cartInfo?.cartItems.toString()}")
}
}
}
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
val cartInfo = viewModel.cartInfo
Log.d("debug", cartInfo.toString())
LazyColumn {
items(cartInfo.value!!.cartItems) {
Card(modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.clickable {
viewModel.increaseQty(it.product, user)
}) {
Row() {
Text(
text = "${it.product.name}",
modifier = Modifier.weight(1f).padding(10.dp)
)
Text(
text = "qty: ${it.qty}"
)
}
}
}
}
}
}
}
}
}
提前致谢
最佳答案
在此行 _cartInfo.value = cartInfo
中,您在 _cartInfo
中设置相同的对象。
可变状态无法检查内部对象的状态是否已更改,它只能检查是否是同一个对象。
您可以将 CartInfo
设为一个数据类,这样您就可以使用 copy
轻松创建新对象。确保不使用任何 var
或可修改的集合(例如 MutableList
),以减少出错的可能性。查看Why is immutability important in functional programming? .
data class CartInfo(val id: String, val cartItems: List<Item>)
// usage
_cartInfo.value = cartInfo.copy(cartItems = cartItems)
关于android-jetpack-compose - 当包含对象内部发生更改时,Jetpack Compose LazyColum 状态不会更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71862136/