android-jetpack-compose - 当包含对象内部发生更改时,Jetpack Compose LazyColum 状态不会更改

标签 android-jetpack-compose android-jetpack android-viewmodel android-mvvm

enter image description here

下面是一个简单的购物车实现,其中如果单击列表项,则 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/

相关文章:

java - 如何在 ViewModel 中将 LiveData<List<User>> 转换为 LiveData<List<String>> ?

android - 工具属性 - Jetpack Compose 中的示例资源

android - Jetpack Compose 离散 slider 未显示确切的数字

android - 在 Jetpack compose 中添加抽屉切换按钮

android - 每当列表发生变化时,LazyList 都会重新组合项目

java - 进行单元测试时无法将Value 设置为 MutableLiveData - 抛出 java.lang.reflect.InvocableTargetException

android - 无法实例化 fragment androidx.navigation.fragment.NavHostFragment

android - 导航架构组件 - 带有 CollapsingToolbar 的详细 View

android - 导航图动画不工作问题 Android

android - 每个屏幕有多个 View 模型