Добавьте сборщиков в ваше приложение

Android предоставляет пользователю элементы управления для выбора времени или даты в виде готовых к использованию диалоговых окон. Эти средства выбора предоставляют элементы управления для выбора каждой части времени (час, минута, AM/PM) или даты (месяц, день, год).

Пример выбора времени с сайта Material.io
Рис. 1. Выбор часа в средстве выбора мобильного календаря.

Использование этих средств выбора помогает гарантировать, что ваши пользователи смогут выбрать действительное время или дату, отформатированные правильно и адаптированные к языковому стандарту пользователя.

Пример модального выбора даты с сайта Material.io
Рисунок 2. Модальный выбор даты.

Мы рекомендуем использовать DialogFragment для размещения каждого средства выбора времени или даты. DialogFragment управляет жизненным циклом диалога и позволяет отображать средства выбора в различных конфигурациях макета, например в базовом диалоговом окне на мобильных телефонах или в качестве встроенной части макета на больших экранах.

Создайте средство выбора времени

Чтобы отобразить TimePickerDialog с помощью DialogFragment , определите класс фрагмента, который расширяет DialogFragment , и верните TimePickerDialog из метода onCreateDialog() фрагмента.

Расширьте DialogFragment для выбора времени

Чтобы определить DialogFragment для TimePickerDialog , выполните следующие действия:

  • Определите метод onCreateDialog() для возврата экземпляра TimePickerDialog .
  • Реализуйте интерфейс TimePickerDialog.OnTimeSetListener для получения обратного вызова, когда пользователь устанавливает время.

Вот пример:

Котлин

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.
    }
}

Ява

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" />

Когда пользователь нажимает эту кнопку, система вызывает следующий метод:

Котлин

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Ява

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 для получения обратного вызова, когда пользователь устанавливает дату.

Вот пример:

Котлин

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.
    }
}

Ява

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"/>

Когда пользователь нажимает эту кнопку, система вызывает следующий метод:

Котлин

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Ява

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 :

  1. Создайте класс, который наследуется от EditText .
  2. Реализуйте метод getAutofillType() , который возвращает AUTOFILL_TYPE_DATE .
  3. Реализуйте метод getAutofillValue() , который возвращает объект AutofillValue , представляющий дату в миллисекундах. Чтобы создать возвращаемый объект, используйте метод forDate() для создания объекта AutofillValue .
  4. Реализуйте метод autofill() . Этот метод предоставляет логику для обработки параметра AutofillValue , который имеет тип AUTOFILL_TYPE_DATE . Чтобы обработать параметр, создайте его правильное строковое представление, например mm/yyyy . Используйте строковое представление, чтобы установить свойство text вашего представления.
  5. Реализуйте функциональность, которая отображает средство выбора, когда пользователь хочет отредактировать дату в пользовательском подклассе EditText . Представление обновляет свойство text , добавляя в него строковое представление значения, которое пользователь выбирает в средстве выбора.

Пример подкласса EditText , который обрабатывает значения AUTOFILL_TYPE_DATE , см. в примере Autofill Framework на Java или Kotlin .

Дополнительные сведения о проверке поддержки автозаполнения для ваших пользовательских представлений см. в разделе Платформа автозаполнения .