从 mutableStateListOf 中删除项目它保留已删除的 TextField 的值,将此值传递给下面的另一个 TextField

deleting item from a mutableStateListOf it keeps the value of the deleted TextField passing this value to the other TextField below

mutableStateListOf 中删除项目,它会保留已删除的 TextField 的值,将此值传递给下面的另一个 TextField。我不知道这是否是 Jetpack Compose 的错误。

这有点令人困惑,因为我删除了第一行。

我的代码:

private var ids = mutableStateListOf<ShoppingCart>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            i = intent.getParcelableArrayListExtra("produtos")!!
            ids=i.toMutableSet().toMutableStateList()

            ids = remember { ids }
                
            MainContent()
        }
    }

LazyColumn(
    modifier = Modifier
    .padding(top = 50.dp)
    .weight(1f)
    .border(4.dp, colorResource(id = R.color.pastel_green))
    ) {
        itemsIndexed(ids) { index, item ->

            var quantidades by rememberSaveable(stateSaver = TextFieldValue.Saver) {
                mutableStateOf(TextFieldValue(item.product_quant.toString()))
            }


            TextField(
                    value = quantidades,
                    onValueChange = {
                        quantidades = it

                        if (it.text.isNotEmpty()) {
                            item.product_quant = it.text.toInt()
                            calcular()
                        }
                    },
                    shape = RoundedCornerShape(8.dp),
                    colors = TextFieldDefaults.textFieldColors(
                            focusedIndicatorColor = Color.Transparent,
                            unfocusedIndicatorColor = Color.Transparent,
                            disabledIndicatorColor = Color.Transparent

                    ),
                    keyboardOptions = KeyboardOptions(
                            keyboardType = KeyboardType.Number
                    ),
                    modifier = Modifier
                        .width(70.dp)
                        .height(70.dp)
                        .padding(top = 20.dp)

            )


            Button(
                    onClick = {
                        ids.removeAt(index)
                        
                    },
                    modifier = Modifier
                        .padding(top = 20.dp, end = 20.dp)
            ) {
                Icon(
                        Icons.Default.Delete,
                        stringResource(id = R.string.deletar)
                )
            }
        }

当您使用惰性视图的 items 时,它会根据 key.

创建一个范围

当您不传递键时,默认值为项目索引。

里面的所有 remember 值都绑定到那个键,所以当你删除第一个单元格时,第二个单元格会重用它记住值,这就是你的情况。您可以传递一些项目 id 来防止这种情况发生。

但是如果您有很多项目并且想要滚动您的列表,您会发现这些项目没有被保存。您可以创建一个可变状态列表,但它会在屏幕旋转期间被清除。

我强烈建议您不要将状态变量存储为全局变量。

取而代之的是,所有应该共享的数据和您不想丢失的数据都应该放在 view model. It's gonna be shared in the whole composable tree, unless you're using compose navigation. For this case check out 共享方式中。

由于您需要修改product_quant,建议您将其设置为可变状态,这样修改会触发重组。

如果您无法更新 ShoppingCart,您可以创建一个 ShoppingCartState 包装器,它将具有可变状态并更新 ShoppingCart 值(如果您需要):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val produtos = intent.getParcelableArrayListExtra("produtos")!!
    setContent{
        // initializing view model with produtos
        viewModel<ScreenViewModel>(
            factory = object : ViewModelProvider.Factory {
                override fun <T : ViewModel?> create(modelClass: Class<T>) =
                    ScreenViewModel(produtos) as T
            }
        )
        TestView()
    }
}
class ShoppingCartState(val shoppingCart: ShoppingCart) {
    private val _product_quant = mutableStateOf(shoppingCart.product_quant)
    var product_quant: Int
        get() = _product_quant.value
        set(value) {
            _product_quant.value = value
            shoppingCart.product_quant = value
        }
}

class ScreenViewModel(ids: List<ShoppingCart>) : ViewModel() {
    val shoppingCartStates = ids.map(::ShoppingCartState).toMutableStateList()

    fun calcular() {
        // do your calculations
    }
}

@Composable
fun TestView() {
    // you can pass view model as a parameter, but this also
    // will return same view model across whole composable tree
    val viewModel = viewModel<ScreenViewModel>()
    LazyColumn(
        modifier = Modifier
            .padding(top = 50.dp)
            .border(4.dp, Color.Green)//colorResource(id = R.color.pastel_green))
    ) {
        itemsIndexed(viewModel.shoppingCartStates) { index, item ->
            Row {
                TextField(
                    value = item.product_quant.toString(),
                    onValueChange = {
                        if (it.isNotEmpty()) {
                            item.product_quant = it.toInt()
                            viewModel.calcular()
                        }
                    },
                    shape = RoundedCornerShape(8.dp),
                    colors = TextFieldDefaults.textFieldColors(
                        focusedIndicatorColor = Color.Transparent,
                        unfocusedIndicatorColor = Color.Transparent,
                        disabledIndicatorColor = Color.Transparent

                    ),
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Number
                    ),
                    modifier = Modifier
                        .width(70.dp)
                        .height(70.dp)
                        .padding(top = 20.dp)

                )


                Button(
                    onClick = {
                        viewModel.shoppingCartStates.removeAt(index)
                    },
                    modifier = Modifier
                        .padding(top = 20.dp, end = 20.dp)
                ) {
                    Icon(
                        Icons.Default.Delete,
                        "delete"
                        //stringResource(id = R.string.deletar)
                    )
                }
            }
        }
    }
}