Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CalendarView Jetpack Compose Buttons Are Not Displayed

I have the following requirement: the user can enter a name in the first text field of a dialog, but when the user clicks on the second (disabled) text field a DatePicker is supposed to open.

I've implemented a Date Picker following some instructions on SO, but I've run into a weird UI bug with the buttons below the CalendarView.

This is my Composable for the Date Picker including a 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
                    )
                }
            }
        }
    )
}

The issue is:

  • when the dialog with the two input fields for name and date opens and I click on the Date field, the buttons of the DatePicker are displayed:

  • when the dialog opens and I edit the name and then click on the Date field, the buttons are not displayed:

I've also cleared the focus using FocusManager just in case this is some issue with the keyboard but that didn't help either.

Any help would be greatly appreciated :)

like image 681
susosaurus Avatar asked Oct 22 '25 10:10

susosaurus


1 Answers

In case anyone else faces this issue, I finally figured out what the problem is.

It's basically an issue between the open keyboard and how the Dialog() Composable calculates the height of the dialog. Because the Dialog() Composable calculates the available height before the keyboard is fully closed, the calculated height is smaller than the actual available height for the Dialog.

So you can either:

  • not use the Dialog() Composable in this case or
  • use a tiny delay between closing the keyboard and opening the dialog (which works but I would not recommend it).

If you want to debug this issue, the following function in the Dialog() Composable is a good place to start:

override fun internalOnMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
like image 117
susosaurus Avatar answered Oct 25 '25 02:10

susosaurus