从 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)
)
}
}
}
}
}
从 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)
)
}
}
}
}
}