CalendarView Jetpack Compose按钮未显示

4
我有以下需求:用户可以在对话框的第一个文本字段中输入名称,但是当用户单击第二个(已禁用)文本字段时,应该打开一个DatePicker。 我已经按照SO上的一些说明实现了一个日期选择器,但是我遇到了一个奇怪的UI错误,与CalendarView下面的按钮有关。
这是我的Compose代码,包括CustomCalendarView:
@Composable
fun JourneyDatePicker(
    isVisible: Boolean = false,
    date: Long?,
    onDateSelected: (Long) -> Unit,
    onDismissRequest: () -> Unit
) {
    var selectedDate by remember {
        mutableStateOf(
            when {
                date != null && date > 0L -> date
                else -> DateTime.now().millis
            }
        )
    }

    if (isVisible) Dialog(
        onDismissRequest = onDismissRequest,
        properties = DialogProperties()
    ) {
        Column(
            modifier = Modifier
                .wrapContentSize()
                .background(
                    shape = RoundedCornerShape(size = 16.dp)
                )
        ) {
            Column(
                Modifier
                    .defaultMinSize(minHeight = 72.dp)
                    .fillMaxWidth()
                    .background(
                        shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
                    )
                    .padding(16.dp)
            ) {
                Text(
                    text = "Datum auswählen"
                )
                Spacer(modifier = Modifier.size(24.dp))
                Text(
                    text = DateTime().withMillis(selectedDate).toString(DateTimeFormat.longDate())
                )
                Spacer(modifier = Modifier.size(16.dp))
            }
            CustomCalendarView(
                date = selectedDate,
                onDateSelected = {
                    selectedDate = it
                }
            )
            Spacer(modifier = Modifier.size(8.dp))
            Row(
                modifier = Modifier
                    .align(Alignment.End)
                    .padding(bottom = 16.dp, end = 16.dp)
            ) {
                TextButton(
                    onClick = {
                        selectedDate = DateTime.now().millis
                        onDismissRequest()
                    }
                ) {
                    Text(
                        text = "Cancel",
                        color = Color.Black
                    )
                }
                TextButton(
                    onClick = {
                        onDateSelected(selectedDate)
                        onDismissRequest()
                    }
                ) {
                    Text(
                        text = "OK",
                        color = Color.Black
                    )
                }
            }
        }
    }
}

@Composable
fun CustomCalendarView(
    date: Long?,
    onDateSelected: (Long) -> Unit
) {
    AndroidView(
        modifier = Modifier.wrapContentSize(),
        factory = { context ->
            CalendarView(ContextThemeWrapper(context, R.style.DatePickerCustom))
        },
        update = { view ->
            view.apply {
                date?.let { d ->
                    if (d > 0L) setDate(d) else DateTime.now().millis
                }
                setOnDateChangeListener { _, year, month, dayOfMonth ->
                    onDateSelected(
                        DateTime
                            .now()
                            .withMonthOfYear(month + 1)
                            .withYear(year)
                            .withDayOfMonth(dayOfMonth)
                            .millis
                    )
                }
            }
        }
    )
}

问题是:
  • 当打开包含名称和日期两个输入字段的对话框并单击日期字段时,DatePicker的按钮将显示:

  • 当对话框打开并编辑名称后,再单击日期字段,则不会显示按钮:

我已经使用FocusManager清除了焦点,以防这是键盘问题,但也没有帮助。

非常感谢任何帮助 :)


请提供一个最小可重现示例这里是我的示例,我没有遇到过这样的问题。如果您可以使用我的代码重现它,那么可能与平台有关。 - Phil Dukhov
是的,我可以使用你的代码重现它。按钮也没有显示。https://pasteboard.co/BzwShLFbGPr7.png - susosaurus
1个回答

2
如果其他人面临此问题,我最终找出了问题所在。这基本上是打开键盘和Dialog() Composable如何计算对话框高度之间的问题。因为Dialog() Composable在键盘完全关闭之前计算可用高度,所以计算出的高度小于对话框实际可用高度。因此,你可以选择:不在此情况下使用Dialog() Composable或在关闭键盘并打开对话框之间使用微小延迟(这有效,但我不建议这样做)。如果你想调试此问题,请从Dialog() Composable中的以下函数开始:
override fun internalOnMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)

除了找出原因,你成功解决了这个问题吗?我在一个带有文本框的可滚动列上遇到了同样的问题。如果我先打开日历,那么一切正常。但是如果我先聚焦于文本框,然后再打开日历,那么取消和确定按钮就不可见了。 - ziselos
1
是的,有点这样。我通过不使用开箱即用的Dialog() Composable,而是构建一个类似对话框的自定义组件来解决它。那时候这是最好的解决方案 :) - susosaurus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接