У меня есть TextField только для чтения, который принимает значение из DatePicker (не компонуемое). Проблема в том, что при изменении значения TextField обратный вызов onValueChange не вызывается. Когда я пытаюсь изменить значение с помощью пользовательского ввода (make readonly = false), я работаю нормально. Итак, какие решения для вызова onValueChange без ввода данных пользователем? Некоторый код:

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()
}
0
dbuzin 26 Ноя 2021 в 10:33

1 ответ

Лучший ответ

onValueChange может быть вызван только TextField. Если вы измените текст в TextField вручную, вам нужно будет самостоятельно выполнить те же операции, что и внутри обратного вызова.

Попробуйте этот код:

// 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)
    ...
}
1
Arpit Shukla 26 Ноя 2021 в 10:47
Спасибо, это правильно
 – 
dbuzin
26 Ноя 2021 в 11:11
Большой. Можете ли вы принять ответ? :)
 – 
Arpit Shukla
26 Ноя 2021 в 11:30