Android 为用户提供控件,以便他们可以选择时间或日期作为现成的对话框。这些选择器提供控件,用于选择时间的每个部分(小时、分钟、上午/下午)或日期(月、日、年)。
使用这些选择器有助于确保您的用户可以选择有效的时间或日期,并确保其格式正确且已根据用户的区域设置进行调整。
建议您使用 DialogFragment
来托管每个时间或日期选择器。 DialogFragment
为您管理对话框生命周期,并允许您在不同的布局配置中显示选择器,例如,在手机上的基本对话框中或在大型屏幕上的布局的嵌入部分中。
创建时间选择器
要使用 DialogFragment
显示 TimePickerDialog
,请定义一个扩展 DialogFragment
的片段类,并从片段的 onCreateDialog()
方法返回 TimePickerDialog
。
扩展 DialogFragment 以获取时间选择器
要为 TimePickerDialog
定义 DialogFragment
,请执行以下操作
- 定义
onCreateDialog()
方法以返回TimePickerDialog
的实例。 - 实现
TimePickerDialog.OnTimeSetListener
接口以在用户设置时间时接收回调。
以下是一个示例
Kotlin
class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener { override fun onCreateDialog(savedInstanceState: Bundle): Dialog { // Use the current time as the default values for the picker. val c = Calendar.getInstance() val hour = c.get(Calendar.HOUR_OF_DAY) val minute = c.get(Calendar.MINUTE) // Create a new instance of TimePickerDialog and return it. return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity)) } override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) { // Do something with the time the user picks. } }
Java
public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current time as the default values for the picker. final Calendar c = Calendar.getInstance(); int hour = c.get(Calendar.HOUR_OF_DAY); int minute = c.get(Calendar.MINUTE); // Create a new instance of TimePickerDialog and return it. return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity())); } public void onTimeSet(TimePicker view, int hourOfDay, int minute) { // Do something with the time the user picks. } }
有关构造函数参数的信息,请参阅 TimePickerDialog
类。
现在,您只需要一个将此片段的实例添加到您的活动的事件。
显示时间选择器
在定义了与前面示例类似的 DialogFragment
后,您可以通过创建 DialogFragment
的实例并调用 show()
方法来显示时间选择器。
例如,以下是一个按钮,当点击时,它会调用一个方法来显示对话框
<Button android:id="@+id/pickTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Pick time" />
当用户点击此按钮时,系统会调用以下方法
Kotlin
findViewById<Button>(R.id.pickTime).setOnClickListener { TimePickerFragment().show(supportFragmentManager, "timePicker") }
Java
findViewById<Button>(R.id.pickTime).setOnClickListener { TimePickerFragment().show(supportFragmentManager, "timePicker"); }
此方法在前面示例中定义的 DialogFragment
的新实例上调用 show()
。 show()
方法需要 FragmentManager
的实例以及片段的唯一标签名称。
创建日期选择器
创建 DatePickerDialog
与创建 TimePickerDialog
类似。区别在于您为片段创建的对话框。
要使用 DialogFragment
显示 DatePickerDialog
,请定义一个扩展 DialogFragment
的片段类,并从片段的 onCreateDialog()
方法返回 DatePickerDialog
。
扩展 DialogFragment 以获取日期选择器
要为 DatePickerDialog
定义 DialogFragment
,请执行以下操作
- 定义
onCreateDialog()
方法以返回DatePickerDialog
的实例。 - 实现
DatePickerDialog.OnDateSetListener
接口以在用户设置日期时接收回调。
以下是一个示例
Kotlin
class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener { override fun onCreateDialog(savedInstanceState: Bundle): Dialog { // Use the current date as the default date in the picker. val c = Calendar.getInstance() val year = c.get(Calendar.YEAR) val month = c.get(Calendar.MONTH) val day = c.get(Calendar.DAY_OF_MONTH) // Create a new instance of DatePickerDialog and return it. return DatePickerDialog(requireContext(), this, year, month, day) } override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) { // Do something with the date the user picks. } }
Java
public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current date as the default date in the picker. final Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); // Create a new instance of DatePickerDialog and return it. return new DatePickerDialog(requireContext(), this, year, month, day); } public void onDateSet(DatePicker view, int year, int month, int day) { // Do something with the date the user picks. } }
有关构造函数参数的信息,请参阅 DatePickerDialog
类。
您只需要一个将此片段的实例添加到您的活动的事件。
显示日期选择器
在定义了与前面示例类似的 DialogFragment
后,您可以通过创建 DialogFragment
的实例并调用 show()
来显示日期选择器。
例如,以下是一个按钮,当点击时,它会调用一个方法来显示对话框
<Button android:id="@+id/pickDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Pick date"/>
当用户点击此按钮时,系统会调用以下方法
Kotlin
findViewById<Button>(R.id.pickDate).setOnClickListener { val newFragment = DatePickerFragment() newFragment.show(supportFragmentManager, "datePicker") }
Java
findViewById<Button>(R.id.pickDate).setOnClickListener { val newFragment = DatePickerFragment(); newFragment.show(supportFragmentManager, "datePicker"); }
此方法在前面示例中定义的 DialogFragment
的新实例上调用 show()
。 show()
方法需要 FragmentManager
的实例以及片段的唯一标签名称。
将选择器与自动填充一起使用
2017 年,Android 推出了 自动填充框架,它允许用户保存可以用于填充不同应用程序中表单的数据。选择器可以通过提供 UI 来让用户更改存储日期或时间数据的字段的值,这在自动填充场景中很有用。例如,在信用卡表格中,日期选择器允许用户输入或更改其信用卡的有效期。
由于选择器是对话框,因此它们不会与其他字段一起在活动中显示。为了在选择器不可见时显示选择器数据,您可以使用另一个视图,例如 EditText
,它可以在选择器不可见时显示该值。
EditText
对象天生期望类型为 AUTOFILL_TYPE_TEXT
的自动填充数据。相反,自动填充服务将数据保存为 AUTOFILL_TYPE_DATE
以创建其适当表示形式。为了解决类型不一致问题,建议您创建一个从 EditText
继承并实现正确处理 AUTOFILL_TYPE_DATE
类型的值所需方法的自定义视图。
请按照以下步骤创建可以处理 AUTOFILL_TYPE_DATE
类型的值的 EditText
子类
- 创建一个从
EditText
继承的类。 - 实现
getAutofillType()
方法,该方法返回AUTOFILL_TYPE_DATE
。 - 实现
getAutofillValue()
方法,该方法返回一个AutofillValue
对象,该对象以毫秒为单位表示日期。要创建返回对象,请使用forDate()
方法生成AutofillValue
对象。 - 实现
autofill()
方法。此方法提供处理AutofillValue
参数的逻辑,该参数的类型为AUTOFILL_TYPE_DATE
。要处理该参数,请创建其适当的字符串表示形式,例如mm/yyyy
。使用字符串表示形式设置视图的text
属性。 - 实现当用户想要编辑自定义
EditText
子类中的日期时显示选择器的功能。该视图使用选择器上用户选择的值的字符串表示形式来更新其text
属性。
有关处理 AUTOFILL_TYPE_DATE
值的 EditText
子类的示例,请参阅 Java 或 Kotlin 中的自动填充框架示例。
要详细了解如何为您的自定义视图提供自动填充支持,请参阅 自动填充框架。