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