向你的应用添加选择器

尝试 Compose 方法
Jetpack Compose 是 Android 推荐的 UI 工具包。了解如何在 Compose 中添加组件。

Android 提供了供用户选择时间或日期的控件,作为现成的对话框。这些选择器提供用于选择时间(小时、分钟、AM/PM)或日期(月、日、年)的每个部分的控件。

An example of time picker from material.io
图 1. 移动日历选择器中的小时选择。

使用这些选择器有助于确保您的用户可以选择有效、格式正确且已调整为用户区域设置的时间或日期。

An example of modal date picker from material.io
图 2. 模态日期选择器。

我们建议您使用DialogFragment 来托管每个时间或日期选择器。DialogFragment 为您管理对话框生命周期,并允许您在不同的布局配置中显示选择器,例如在手机上的基本对话框或在大屏幕上作为布局的嵌入部分。

创建一个时间选择器

要使用DialogFragment 显示TimePickerDialog,请定义一个扩展DialogFragment的片段类,并从片段的onCreateDialog()方法返回TimePickerDialog

扩展 DialogFragment 以创建时间选择器

要为TimePickerDialog 定义DialogFragment,请执行以下操作

这是一个示例

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,请执行以下操作

这是一个示例

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的子类

  1. 创建一个从EditText继承的类。
  2. 实现getAutofillType()方法,该方法返回AUTOFILL_TYPE_DATE
  3. 实现getAutofillValue()方法,该方法返回一个表示日期(以毫秒为单位)的AutofillValue对象。要创建返回对象,请使用forDate()方法生成AutofillValue对象。
  4. 实现autofill()方法。此方法提供处理AutofillValue参数的逻辑,该参数的类型为AUTOFILL_TYPE_DATE。要处理该参数,请创建其正确的字符串表示形式,例如mm/yyyy。使用字符串表示形式设置视图的text属性。
  5. 实现当用户想要编辑EditText的自定义子类中的日期时显示选择器的功能。该视图使用用户在选择器上选择的值的字符串表示形式更新text属性。

例如,要了解处理 AUTOFILL_TYPE_DATE 值的 EditText 子类的示例,请参阅 JavaKotlin 中的自动填充框架示例。

要详细了解如何为自定义视图提供自动填充支持,请参阅 自动填充框架