В Android есть готовые диалоговые окна, с помощью которых пользователь может выбрать время или дату. Эти виджеты позволяют выбрать каждую часть времени (час, минута, AM/PM) или даты (месяц, день, год).
Использование этих средств выбора помогает пользователям выбрать дату или время, которые действительны, правильно отформатированы и адаптированы к языковому стандарту пользователя.
Рекомендуем использовать DialogFragment для размещения каждого окна выбора даты или времени. DialogFragment управляет жизненным циклом диалогового окна и позволяет показывать окна выбора в разных конфигурациях макета, например в виде базового диалогового окна на телефонах или встроенной части макета на больших экранах.
Как создать окно выбора времени
Чтобы показать TimePickerDialog с помощью DialogFragment, определите класс фрагмента, который расширяет DialogFragment, и верните TimePickerDialog из метода onCreateDialog() фрагмента.
Расширение DialogFragment для выбора времени
Чтобы определить DialogFragment для TimePickerDialog, выполните следующие действия:
- Определите метод
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.
Теперь вам нужно событие, которое добавляет экземпляр этого фрагмента в объект activity.
Показать окно выбора времени
После того как вы определите 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"); }
Этот метод вызывает show() для нового экземпляра DialogFragment, определенного в предыдущем примере. Метод show() требует экземпляр FragmentManager и уникальное название тега для фрагмента.
Как создать окно выбора даты
Создание DatePickerDialog похоже на создание TimePickerDialog. Разница заключается в диалоге,
который вы создаете для фрагмента.
Чтобы показать DatePickerDialog с помощью DialogFragment, определите класс фрагмента, который расширяет DialogFragment, и верните DatePickerDialog из метода onCreateDialog() фрагмента.
Расширение DialogFragment для окна выбора даты
Чтобы определить DialogFragment для DatePickerDialog, выполните следующие действия:
- Определите метод
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.
Вам нужно только событие, которое добавляет экземпляр этого фрагмента в объект activity.
Показать окно выбора даты
После того как вы определите 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"); }
Этот метод вызывает show() для нового экземпляра DialogFragment, определенного в предыдущем примере. Метод show() требует экземпляр FragmentManager и уникальное название тега для фрагмента.
Как использовать виджеты выбора с автозаполнением
В 2017 году в Android появился фреймворк автозаполнения, который позволяет пользователям сохранять данные для заполнения форм в разных приложениях. Окна выбора могут быть полезны в сценариях автозаполнения, предоставляя пользовательский интерфейс, который позволяет пользователям изменять значение поля, в котором хранятся данные о дате или времени. Например, в форме кредитной карты окно выбора даты позволяет пользователям вводить или изменять срок действия своей кредитной карты.
Поскольку виджеты выбора являются диалоговыми окнами, они не отображаются в действии вместе с другими полями. Чтобы показывать данные, когда окно выбора скрыто, можно использовать другой элемент, например EditText.
Объект EditText по умолчанию ожидает данные автозаполнения типа AUTOFILL_TYPE_TEXT.
Сервисы автозаполнения сохраняют данные в виде AUTOFILL_TYPE_DATE, чтобы создать их подходящее представление. Чтобы решить проблему с несоответствием типов, мы рекомендуем создать специальное представление, которое наследует от EditText и реализует методы, необходимые для правильной обработки значений типа AUTOFILL_TYPE_DATE.
Чтобы создать подкласс EditText, который может обрабатывать значения типа AUTOFILL_TYPE_DATE, выполните следующие действия:
- Создайте класс, наследующий от
EditText. - Реализуйте метод
getAutofillType(), который возвращаетAUTOFILL_TYPE_DATE. - Реализуйте метод
getAutofillValue(), который возвращает объектAutofillValue, представляющий дату в миллисекундах. Чтобы создать возвращаемый объект, используйте методforDate(), который генерирует объектAutofillValue. - Реализуйте метод
autofill(). Этот метод содержит логику для обработки параметраAutofillValue, который относится к типуAUTOFILL_TYPE_DATE. Чтобы обработать параметр, создайте его строковое представление, напримерmm/yyyy. Используйте строковое представление, чтобы задать свойствоtextвашего представления. - Реализуйте функцию, которая показывает окно выбора, когда пользователь хочет изменить дату в пользовательском подклассе
EditText. Представление обновляет свойствоtext, используя строковое представление значения, которое пользователь выбирает в окне выбора.
Пример подкласса EditText, который обрабатывает значения AUTOFILL_TYPE_DATE, можно найти в примере фреймворка автозаполнения на Java или Kotlin.
Подробнее о том, как обеспечить поддержку автозаполнения для пользовательских представлений…