androidandroid-timepickerandroid-jetpack-compose

How to set the result of time picker to TextField


I want to set the result of time picker to TextField, how to achieve it by onValueChange?

@Composable
fun TestTimePickerTextField(
    selectTime: (Context) -> String
) {
    val context = ContextAmbient.current
    TextField(
        // How to pass result to TextField
    )
}

// viewModel
fun selectTime(context: Context): String {
    var time = ""
    val currentDateTime = Calendar.getInstance()
    val startYear = currentDateTime.get(Calendar.YEAR)
    val startMonth = currentDateTime.get(Calendar.MONTH)
    val startDay = currentDateTime.get(Calendar.DAY_OF_MONTH)
    val startHour = currentDateTime.get(Calendar.HOUR_OF_DAY)
    val startMinute = currentDateTime.get(Calendar.MINUTE)
    DatePickerDialog(context, { _, year, month, day ->
        TimePickerDialog(context, { _, hour, minute ->
            val pickedDateTime = Calendar.getInstance()
            pickedDateTime.set(year, month, day, hour, minute)
            time = "$year-$month-$day $hour:$minute"
        }, startHour, startMinute, false).show()
    }, startYear, startMonth, startDay).show()
    return time
}

Solution

  • ViewModel shouldn't contain methods with context. Put all android-related codeto activty/fragment.

    In Activity:

    @Composable
    fun init() {
        val time by viewModel.time.observeAsState()
        MaterialTheme {
            Column {
                TextButton(onClick = { selectTime() }) {
                    Text("Select time")
                }
                Text(time ?: "no time set")
            }
        }
    }
    
    private fun selectTime(): String {
        var time = ""
        val currentDateTime = Calendar.getInstance()
        val startYear = currentDateTime.get(Calendar.YEAR)
        val startMonth = currentDateTime.get(Calendar.MONTH)
        val startDay = currentDateTime.get(Calendar.DAY_OF_MONTH)
        val startHour = currentDateTime.get(Calendar.HOUR_OF_DAY)
        val startMinute = currentDateTime.get(Calendar.MINUTE)
        DatePickerDialog(this, { _, year, month, day ->
            TimePickerDialog(context, { _, hour, minute ->
                val pickedDateTime = Calendar.getInstance()
                pickedDateTime.set(year, month, day, hour, minute)
                time = "$year-$month-$day $hour:$minute"
                viewModel.updateTime(time)
            }, startHour, startMinute, false).show()
        }, startYear, startMonth, startDay).show()
        return time
    }
    

    ViewModel class:

    class MainViewModel : ViewModel() {
    
    var time = MutableLiveData<String>()
    
    fun updateTime(time: String) {
        this.time.value = time
    }
    }