dbuzin
dbuzin

Reputation: 365

TextField onValueChanged not calling

I have a readonly TextField that takes value from DatePicker (not composable). The problem is that when value of TextField changes the onValueChange callback doesn't calls. When i try to change value via user input (make readonly = false) i works fine. So any solutions to call onValueChange without user input? Some code:

val start = remember { mutableStateOf(state.timeStart) }

OutlinedTextField(
    value = DateTimeConverter.formatLogsTime(start.value),
    onValueChange = {
        start.value = DateTimeConverter.logDateToEpoch(it)!!
        onEvent(Logs.Event.TimeStartChanged(start.value))
    },
    colors = TextFieldDefaults.textFieldColors(
        backgroundColor = Color.White,
        unfocusedIndicatorColor = Color.Transparent,
        focusedIndicatorColor = Color.Transparent
    ),
    textStyle = textStyle,
    modifier = Modifier
        .fillMaxWidth()
        .padding(20.dp)
        .background(
                    LightLightGray,
                    RoundedCornerShape(8.dp)
         ),
         trailingIcon = {
             Icon(
                 Icons.Rounded.DateRange, "DateRange",
                 Modifier.clickable { createDateTimePicker(currentContext, start) })
         },
         readOnly = true
)

private fun createDateTimePicker(
    context: Context,
    dateHolder: MutableState<Long>
) {
    val calendar = Calendar.getInstance()
    val listener = OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
        calendar.set(Calendar.YEAR, year)
        calendar.set(Calendar.MONTH, monthOfYear)
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
        val rawDate = "$dayOfMonth.$monthOfYear.$year 23:59:59"
        val newDate = DateTimeConverter.logDateToEpoch(rawDate)
        if (newDate != null)
            dateHolder.value = newDate
    }
    val picker = DatePickerDialog(context, listener, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH))
    picker.show()
}

Upvotes: 0

Views: 982

Answers (1)

Arpit Shukla
Arpit Shukla

Reputation: 10523

onValueChange can only be invoked by the TextField. If you change the text in TextField manually, you need to perform the same operations which you do inside the callback yourself.

Try this code:

// Inside Modifier.clickable
createDateTimePicker(currentContext) { date ->
    start.value = date
    onEvent(Logs.Event.TimeStartChanged(start.value))
}

// Now your function will be
private fun createDateTimePicker(
    context: Context,
    onDateChange: (Long) -> Unit
) {
    ...
    if (newDate != null)
        onDateChange(newDate)
    ...
}

Upvotes: 2

Related Questions