.
I want my code to remove elements from list of text fields properly. Each element has an X button to remove it's text field. If I start removing elements from the bottom it works but it doesn't work for removing random elements I want to use forEachIndexed for displaing the list Please help me with solving this problem. I've been trying to do this for some time but every trial is unsuccessful.
This is a piece of code that I've managed to write but removing elements doesn't work properly
val listOfWords = mutableStateListOf<String>()
@Composable
fun Main() {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Words",
modifier = Modifier.padding(0.dp, 0.dp, 0.dp, 4.dp),
style = MaterialTheme.typography.h6
)
listOfWords.forEachIndexed { index, word ->
Input(word, 30, "Word", 1,
{newWord ->
listOfWords[index] = newWord
Log.d("text ",word)
},
{
listOfWords.removeAt(index)
}
)
}
IconButton(
onClick = {
listOfWords.add("")
}
) {
Icon(
imageVector = Icons.Filled.Add,
contentDescription = "Add"
)
}
}
}
@Composable
fun Input(
word: String,
maxChar: Int,
label: String,
maxLines: Int,
onEdit: (word: String) -> (Unit),
onRemove: () -> (Unit)
) {
var text by remember { mutableStateOf(word) }
Column(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp, 0.dp, 8.dp, 0.dp)
) {
OutlinedTextField(
value = text,
onValueChange = {
if (it.length <= maxChar) text = it
onEdit(text)
},
modifier = Modifier.fillMaxWidth(),
label = { Text(label) },
leadingIcon = {
Icon(Icons.Default.Edit, null)
},
trailingIcon = {
IconButton(onClick = {
onRemove()
}) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = "Back"
)
}
},
maxLines = maxLines
)
Text(
text = "${text.length} / $maxChar",
textAlign = TextAlign.End,
style = MaterialTheme.typography.caption,
modifier = Modifier
.fillMaxWidth()
.padding(end = 16.dp)
)
}
}
The problem is here.
var text by remember { mutableStateOf(word) }
Without supplying a key to Input's remember, compose will not be able refresh/update your remaining Input's states during Main's re-composition every time an Input is removed.
You can use the word parameter as key for remember to re-calculate every composition pass (i.e when you add/remove or typed a value in the TextField), and your code should probably work as you expected.
var text by remember(word) { mutableStateOf(word) }
Have you tried doing the following instead?
listOfWords.forEachIndexed { index, word ->
... // rest of code
{
listOfWords.removeAt(index)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With