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 :)
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:
Dialog() Composable in this case orIf 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With