I am showing a list of rows with one word in it, inside a LazyColumn. On clicking the row, an edit form opens. The data is coming from a room database.
Since the row is on a separate composable function, I can open many different edit forms together (one in each row). But I want to show only one edit form in the whole list at a time. If I click one row to open an edit form, the rest of the open forms on the other rows should be closed. How can I do that?
Here is the code:
val words: List<Word> by wordViewModel.allWords.observeAsState(listOf())
var newWord by remember { mutableStateOf("") }
val context = LocalContext.current
val keyboardController = LocalSoftwareKeyboardController.current
LazyColumn(
modifier = Modifier
.weight(1f)
.padding(vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
items(words) { word ->
WordItemLayout(
word = word,
onSaveUpdatedWord = { onUpdateWord(it) },
onTrashClicked = { onDeleteWord(it) }
)
}
}
@Composable
fun WordItemLayout(word: Word, onSaveUpdatedWord: (Word) -> Unit, onTrashClicked: (Word) -> Unit) {
var showEditForm by remember { mutableStateOf(false) }
var editedWord by remember { mutableStateOf(word.word) }
val context = LocalContext.current
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primaryVariant)
.padding(vertical = 12.dp, horizontal = 24.dp)
.clickable {
showEditForm = !showEditForm
editedWord = word.word
},
verticalAlignment = Alignment.CenterVertically,
) {
Image(painter = painterResource(R.drawable.ic_star), contentDescription = null)
Text(
text = word.word,
color = Color.White,
fontSize = 20.sp,
modifier = Modifier
.padding(start = 16.dp)
.weight(1f)
)
// Delete Button
IconButton(
onClick = {
showEditForm = false
onTrashClicked(word)
Toast.makeText(context, "Word deleted", Toast.LENGTH_SHORT).show()
},
modifier = Modifier.size(12.dp)
) {
Icon(
imageVector = Icons.Filled.Delete,
contentDescription = "Delete Word",
tint = Color.White
)
}
}
// word edit form
if (showEditForm) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.Bottom
) {
TextField(
value = editedWord,
onValueChange = { editedWord = it },
modifier = Modifier.weight(1f),
colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White) // TextField Background Color
)
// Update Button
Button(
onClick = {
val updatedWord: Word = word
if (updatedWord.word != editedWord.trim()) {
updatedWord.word = editedWord.trim()
onSaveUpdatedWord(updatedWord)
Toast.makeText(context, "Word updated", Toast.LENGTH_SHORT).show()
}
showEditForm = false
},
modifier = Modifier.padding(start = 8.dp)
) {
Icon(imageVector = Icons.Filled.Done, contentDescription = "Update Word")
}
}
}
}
}
Thanks for your help!