我有一个统计屏幕,使用下拉菜单来添加过滤器。例如,一个过滤器包含所有游戏类型,每个游戏旁边都有复选框。它最初填充了所有选中的框,因此所有游戏都包含在统计数据中。当用户取消选中游戏时,统计数据会更新,而不会更新未选中的游戏。一切都按我想要的方式工作,除了统计信息在我关闭下拉菜单之前不会显示更新的值。复选框在选中时会更新。我使用调试来查看统计信息在选中或取消选中复选框时更新。
val selectedGame = remember { SnapshotStateList<String>() }
ExposedDropdownMenuBox(
expanded = expandedGame,
onExpandedChange = { onExpandGameChange(it) },
) {
ShowOutlinedTextField(
readOnly = true,
value = stringResource(id = R.string.game_filter),
modifier = Modifier
.padding(10.dp)
.menuAnchor(type = MenuAnchorType.PrimaryNotEditable,
enabled = true)
)
ExposedDropdownMenu(
expanded = expandedGame,
onDismissRequest = { onExpandGameChange(false) }
) {
gameNames.forEach { game ->
DropdownMenuItem(
onClick = { onExpandGameChange(false) },
text = {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked =
selectedGame.contains(game.gameName),
onCheckedChange = { isChecked ->
if (isChecked) {
selectedGame.add(game.gameName)
} else {
selectedGame.remove(game.gameName)
}
setSelectedGames(selectedGame.toList())
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = game.gameName)
}
}
)
}
}
}
我尝试添加以下代码,但没有成功。
var forceRecomposition by remember { mutableStateOf(0) }
Checkbox(
checked = selectedLocations.contains(casino.name),
onCheckedChange = { isChecked ->
if (isChecked) {
selectedLocations.add(casino.name)
} else {
selectedLocations.remove(casino.name)
}
setSelectedCasinos(selectedLocations.toList())
forceRecomposition++
}
)
您应该将
ExposedDropdownMenu
可组合项和您的统计可组合项所共有的状态提升到共同的父可组合项。然后,当用户单击 Checkbox
,
请看下面的示例代码:
@Composable
fun MyComposableScreen() {
val items = remember { arrayOf("Item A", "Item B", "Item C", "Item D") }
val selectedItems = remember { mutableStateListOf(*items) }
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceAround,
horizontalAlignment = Alignment.CenterHorizontally
) {
MyDropdownMenu(
allItems = items.toList(),
selectedItems = selectedItems,
addItem = { newItem ->
selectedItems.add(newItem)
},
removeItem = { removedItem ->
selectedItems.remove(removedItem)
}
)
MyStatistics(selectedItems)
}
}
MyDropdownMenu
可组合项如下所示:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyDropdownMenu(
allItems: List<String>,
selectedItems: List<String>,
addItem: (String) -> Unit,
removeItem: (String) -> Unit
) {
var isExpanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = isExpanded,
onExpandedChange = { isExpanded = it },
) {
TextField(
modifier = Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable),
state = TextFieldState(selectedItems.joinToString(",")),
readOnly = true,
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded) },
colors = ExposedDropdownMenuDefaults.textFieldColors(),
)
ExposedDropdownMenu(
expanded = isExpanded,
onDismissRequest = { isExpanded = false }
) {
allItems.forEach { itemName: String ->
DropdownMenuItem(
onClick = { /** do nothing or call addItem() / removeItem() **/ },
text = {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = selectedItems.contains(itemName),
onCheckedChange = { isChecked ->
if (isChecked) {
addItem(itemName)
} else {
removeItem(itemName)
}
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = itemName)
}
}
)
}
}
}
}
最后,
MyStatistics
可组合项可能如下所示:
@Composable
fun MyStatistics(selectedItems: List<String>) {
Text(
"SELECTED ITEMS: \n${selectedItems.joinToString(",")}",
fontSize = 24.sp
)
}
请注意,最好使用
mutableStateListOf
而不是直接 remember
SnapshotStateList
。
输出: