单击一次EditText后显示DatePickerDialog和TimePickerDialog

问题描述

在Androidviewmodel上单击EditText之后,我试图显示DataPickerDialog和TimePickerDialog。

<!-- inside some window or user control -->
<ToggleButton x:Name="tbCasetoggle" />
<custom:TextButtonControl Text="some text" Capitalised="{Binding ElementName=tbCasetoggle,Path=IsChecked}" />

xml(数据绑定)

// fragment

// in TestFragment
// pass the `requireActivity().application` to Textviewmodel

// viewmodel

class Testviewmodel(
    application: Application,) : Androidviewmodel(application) {
    ...
    fun showDateTimeDialog() {
        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(getApplication(),{ _,year,month,day ->
            TimePickerDialog(getApplication(),hour,minute ->
                val pickedDateTime = Calendar.getInstance()
                pickedDateTime.set(year,day,minute)
            },startHour,startMinute,false).show()
        },startYear,startMonth,startDay).show()
    }
}

但是,当我单击此EditText时,它报告一个错误,表明在显示这两个对话框时活动已消失。

android.view.WindowManager $ BadTokenException:无法添加窗口-令牌null无效;您的活动正在进行吗?

解决方法

原因是上下文。 对话框的上下文必须是活动而不是应用程序。 将应用程序上下文设置为对话框将导致WindowManger $ BadTokenException。

,
import android.app.Application
import androidx.lifecycle.AndroidViewModel

class TestViewModel(application: Application) : AndroidViewModel(application) {

    private val context = getApplication<Application>().applicationContext  
     ........
} 

然后通过上下文

 fun showDateTimeDialog() {
        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,day,minute)
            },startHour,startMinute,false).show()
        },startYear,startMonth,startDay).show()
    }
}