Compose 中的 DropdownMenu 在 LazyColum 中的每个 Morevert 图标中打开
DropdownMenu in Compose opens in every Morevert icon in LazyColum
我在编写 DropdownMenu
时遇到问题。问题是当我单击图标以显示菜单时,它不仅显示在 LazyColum
中的每个更多图标中,而且还显示在单击的图标中,如下图所示:
代码截图:
var expanded by remember { mutableStateOf(false) }
LazyColumn(contentPadding = PaddingValues(16.dp)) {
items(items = schedules) { schedule ->
TimetableItem(
navigator = navigator,
viewModel = viewModel,
schedule = schedule,
expanded = expanded,
onExpandedChange = {expanded = it}
)
}
}
@Composable
fun TimetableItem(
navigator: DestinationsNavigator,
viewModel: TimetableViewModel,
schedule: TimetableEntity,
expanded: Boolean,
onExpandedChange: (Boolean) -> Unit
) {
Card(
modifier = Modifier
.padding(bottom = 16.dp)
.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
elevation = 8.dp
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier
.align(Alignment.Center),
text = "${schedule.timeFrom} - ${schedule.timeTo}",
fontSize = 16.sp
)
IconButton(
onClick = { onExpandedChange(true)},
modifier = Modifier.align(Alignment.CenterEnd)
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.more_option)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { onExpandedChange(false) }
) {
val options = listOf(R.string.delete_option,R.string.edit_option)
options.forEachIndexed { index, option ->
DropdownMenuItem(
onClick = {
onExpandedChange(false)
when(index){
0 -> viewModel.onDeleteSchedule(schedule)
1 -> navigator.navigate(AddEditLectureScreenDestination(timetableEntity = schedule)) }
}
) { Text(stringResource(option))}
}
}
}
}
由于您有多个下拉菜单,因此不能对所有菜单使用相同的布尔变量。
在多选的情况下你需要创建一个list/map的被选项目,但在这种情况下只能选择一个drop-down菜单,所以你可以存储一个可选的被选项目(或其索引)像这样:
val expandedSchedule = remember { mutableStateOf<TimetableEntity?>(null) }
LazyColumn(contentPadding = PaddingValues(16.dp)) {
items(items = schedules) { schedule ->
TimetableItem(
navigator = navigator,
viewModel = viewModel,
schedule = schedule,
expanded = expandedSchedule == schedule,
onExpandedChange = { expanded ->
expandedSchedule = schedule.takeIf { expanded }
}
)
}
}
你的问题是你所有的 ExpandedItems
共享相同的 expandedState
您还可以简化代码:
@Composable
fun TimetableItem(
schedule: TimetableEntity,
expanded: Boolean = false,
onClick: (index: Int) -> Unit
) {
var expandedState by remember { mutableStateOf(expanded) }
Card(
modifier = Modifier
.padding(bottom = 16.dp)
.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
elevation = 8.dp
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier
.align(Alignment.Center),
text = "${schedule.timeFrom} - ${schedule.timeTo}",
fontSize = 16.sp
)
IconButton(
onClick = { expandedState = true},
modifier = Modifier.align(Alignment.CenterEnd)
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.more_option)
)
DropdownMenu(
expanded = expandedState,
onDismissRequest = { expandedState = false }
) {
val options = listOf(R.string.delete_option,R.string.edit_option)
options.forEachIndexed { index, option ->
DropdownMenuItem(
onClick = {
expandedState = false
onClick(index)
}
) { Text(stringResource(option))}
}
}
}
}
在这种情况下,您不再需要太多特定参数:
TimeTableItem(
schedule = schedule,
) { index ->
when(index){
0 -> viewModel.onDeleteSchedule(schedule)
1 ->navigator.navigate(
AddEditLectureScreenDestination(timetableEntity = schedule)
)
}
}
我在编写 DropdownMenu
时遇到问题。问题是当我单击图标以显示菜单时,它不仅显示在 LazyColum
中的每个更多图标中,而且还显示在单击的图标中,如下图所示:
代码截图:
var expanded by remember { mutableStateOf(false) }
LazyColumn(contentPadding = PaddingValues(16.dp)) {
items(items = schedules) { schedule ->
TimetableItem(
navigator = navigator,
viewModel = viewModel,
schedule = schedule,
expanded = expanded,
onExpandedChange = {expanded = it}
)
}
}
@Composable
fun TimetableItem(
navigator: DestinationsNavigator,
viewModel: TimetableViewModel,
schedule: TimetableEntity,
expanded: Boolean,
onExpandedChange: (Boolean) -> Unit
) {
Card(
modifier = Modifier
.padding(bottom = 16.dp)
.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
elevation = 8.dp
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier
.align(Alignment.Center),
text = "${schedule.timeFrom} - ${schedule.timeTo}",
fontSize = 16.sp
)
IconButton(
onClick = { onExpandedChange(true)},
modifier = Modifier.align(Alignment.CenterEnd)
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.more_option)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { onExpandedChange(false) }
) {
val options = listOf(R.string.delete_option,R.string.edit_option)
options.forEachIndexed { index, option ->
DropdownMenuItem(
onClick = {
onExpandedChange(false)
when(index){
0 -> viewModel.onDeleteSchedule(schedule)
1 -> navigator.navigate(AddEditLectureScreenDestination(timetableEntity = schedule)) }
}
) { Text(stringResource(option))}
}
}
}
}
由于您有多个下拉菜单,因此不能对所有菜单使用相同的布尔变量。
在多选的情况下你需要创建一个list/map的被选项目,但在这种情况下只能选择一个drop-down菜单,所以你可以存储一个可选的被选项目(或其索引)像这样:
val expandedSchedule = remember { mutableStateOf<TimetableEntity?>(null) }
LazyColumn(contentPadding = PaddingValues(16.dp)) {
items(items = schedules) { schedule ->
TimetableItem(
navigator = navigator,
viewModel = viewModel,
schedule = schedule,
expanded = expandedSchedule == schedule,
onExpandedChange = { expanded ->
expandedSchedule = schedule.takeIf { expanded }
}
)
}
}
你的问题是你所有的 ExpandedItems
共享相同的 expandedState
您还可以简化代码:
@Composable
fun TimetableItem(
schedule: TimetableEntity,
expanded: Boolean = false,
onClick: (index: Int) -> Unit
) {
var expandedState by remember { mutableStateOf(expanded) }
Card(
modifier = Modifier
.padding(bottom = 16.dp)
.fillMaxSize(),
shape = RoundedCornerShape(5.dp),
elevation = 8.dp
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier
.align(Alignment.Center),
text = "${schedule.timeFrom} - ${schedule.timeTo}",
fontSize = 16.sp
)
IconButton(
onClick = { expandedState = true},
modifier = Modifier.align(Alignment.CenterEnd)
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.more_option)
)
DropdownMenu(
expanded = expandedState,
onDismissRequest = { expandedState = false }
) {
val options = listOf(R.string.delete_option,R.string.edit_option)
options.forEachIndexed { index, option ->
DropdownMenuItem(
onClick = {
expandedState = false
onClick(index)
}
) { Text(stringResource(option))}
}
}
}
}
在这种情况下,您不再需要太多特定参数:
TimeTableItem(
schedule = schedule,
) { index ->
when(index){
0 -> viewModel.onDeleteSchedule(schedule)
1 ->navigator.navigate(
AddEditLectureScreenDestination(timetableEntity = schedule)
)
}
}