当包含对象内部发生更改时,Jetpack Compose LazyColum 状态不会更改
下面是一个简单的购物车实现,如果单击列表项目,则应增加数量的值,
但在ui中以某种方式变化,但不反映在UI中(不使用使用新的数量值)
我认为问题在于这一部分: lazycolumn {items(cartinfo.value !!。cartitems){...}
作为cartitems
不是直接的状态值,这就是为什么不触发lazycolumn ui的重组的原因。
但是不能将此问题解决为mutableStateof< cartinfo?>
是固定的,我不希望mutableStist< 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}"
)
}
}
}
}
}
}
}
}
}
状态
Below is a simple Cart Implementation where the value of qty should increase by 1 if a list item is clicked...
But somehow values in the ViewModel are changing, but not reflected in UI ( not recomposing with new qty value)
I think problem lies in this part :LazyColumn {items(cartInfo.value!!.cartItems){...}
as cartItems
is not directly a state value that's why not triggering the recomposition of the LazyColumn UI.
But cant solve this problem as mutableStateOf<CartInfo?>
is fixed and I don't want a separate state for 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}"
)
}
}
}
}
}
}
}
}
}
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在此行中,
_cartinfo.value = Cartinfo
您在_cartinfo
中设置了相同的对象。可变状态无法检查内部对象的状态是否已更改,它只能检查它是否是同一对象。
您可以使您的
Cartinfo
一个数据类,该类别可轻松创建一个使用复制
的新对象。确保您不使用任何var
或修改的收集,例如mutablelist
来减少错误的机会。查看为什么不可变性在功能编程中很重要? 。In this line
_cartInfo.value = cartInfo
you set the same object in your_cartInfo
.Mutable state cannot check if the state of your internal object has changed, it can only check if it is the same object or not.
You can make your
CartInfo
a data class which allows you to easily create a new object withcopy
. Make sure you do not use anyvar
or modifiable collections such asMutableList
to reduce the chance of error. Check out Why is immutability important in functional programming?.使用
Cartitem(it.product,qty = it.qty + 1)创建新的
解决了问题:cartitem
Creating new
CartItem
withCartItem(it.product, qty = it.qty + 1)
solved the problem: