Dodaj selektory do swojej aplikacji

Android daje użytkownikowi możliwość wyboru godziny i daty w postaci gotowych do użycia okien. Te selektory umożliwiają wybór poszczególnych godzin (godzina, minuta, AM/PM) lub daty (miesiąc, dzień, rok).

Przykład selektora czasu z material.io
Rysunek 1. Wybór godziny w selektorze kalendarza na urządzeniu mobilnym.

Korzystanie z tych selektora pozwala użytkownikom wybrać prawidłową godzinę lub datę, która będzie prawidłowa, odpowiednio sformatowana i dostosowana do ich języka.

Przykład modalnego selektora daty z material.io
Rysunek 2. Modalny selektor daty.

Do hostowania każdego selektora godziny lub daty zalecamy używanie DialogFragment. DialogFragment zarządza cyklem życia okna i umożliwia wyświetlanie selektora w różnych konfiguracjach układu, np. w podstawowym oknie dialogowym na telefonach lub jako część elementu układu na dużych ekranach.

Utwórz selektor godziny

Aby wyświetlić TimePickerDialog z użyciem DialogFragment, zdefiniuj klasę fragmentu, która rozszerza zakres DialogFragment i zwraca TimePickerDialog z metody onCreateDialog() zawartej w tym fragmencie.

Rozszerz DialogFragment dla selektora czasu

Aby zdefiniować DialogFragment dla elementu TimePickerDialog, wykonaj te czynności:

  • Określ metodę onCreateDialog(), która będzie zwracać instancję TimePickerDialog.
  • Zaimplementuj interfejs TimePickerDialog.OnTimeSetListener, aby otrzymywać wywołanie zwrotne po ustawieniu godziny przez użytkownika.

Oto przykład:

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

Informacje o argumentach konstruktora znajdziesz w klasie TimePickerDialog.

Teraz potrzebujesz tylko zdarzenia, które doda wystąpienie tego fragmentu do Twojej aktywności.

Pokaż selektor godziny

Po zdefiniowaniu obiektu DialogFragment, takiego jak w poprzednim przykładzie, możesz wyświetlić selektor godziny, tworząc wystąpienie obiektu DialogFragment i wywołując metodę show().

Na przykład tak wygląda przycisk, który po kliknięciu wywołuje metodę wyświetlającą okno:

<Button
    android:id="@+id/pickTime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick time" />

Gdy użytkownik kliknie ten przycisk, system wywoła następującą metodę:

Kotlin

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

Java

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

Ta metoda wywołuje funkcję show() w nowym wystąpieniu zdarzenia DialogFragment zdefiniowanego w poprzednim przykładzie. Metoda show() wymaga wystąpienia FragmentManager i unikalnej nazwy tagu dla fragmentu.

Tworzenie selektora dat

Tworzenie elementu DatePickerDialog jest jak utworzenie TimePickerDialog. Różnica polega na oknie dialogowym, które tworzysz dla danego fragmentu.

Aby wyświetlić DatePickerDialog z użyciem DialogFragment, zdefiniuj klasę fragmentu, która rozszerza zakres DialogFragment i zwraca DatePickerDialog z metody onCreateDialog() danego fragmentu.

Rozszerz DialogFragment dla selektora daty

Aby zdefiniować DialogFragment dla elementu DatePickerDialog, wykonaj te czynności:

  • Określ metodę onCreateDialog(), która będzie zwracać instancję DatePickerDialog.
  • Zaimplementuj interfejs DatePickerDialog.OnDateSetListener, aby otrzymywać wywołanie zwrotne po ustawieniu daty przez użytkownika.

Oto przykład:

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

Informacje o argumentach konstruktora znajdziesz w klasie DatePickerDialog.

Potrzebujesz tylko zdarzenia, które doda wystąpienie tego fragmentu do Twojej aktywności.

Pokaż selektor dat

Po zdefiniowaniu obiektu DialogFragment tak jak w poprzednim przykładzie, możesz wyświetlić selektor daty, tworząc wystąpienie obiektu DialogFragment i wywołując show().

Na przykład tak wygląda przycisk, który po kliknięciu wywołuje metodę wyświetlającą okno:

<Button
    android:id="@+id/pickDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick date"/>

Gdy użytkownik kliknie ten przycisk, system wywoła następującą metodę:

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");
}

Ta metoda wywołuje funkcję show() w nowym wystąpieniu zdarzenia DialogFragment zdefiniowanego w poprzednim przykładzie. Metoda show() wymaga wystąpienia FragmentManager i unikalnej nazwy tagu dla danego fragmentu.

Używanie selektorów w ramach autouzupełniania

W 2017 roku wprowadziliśmy na Androidzie platformę autouzupełniania, która umożliwia użytkownikom zapisywanie danych do wypełniania formularzy w różnych aplikacjach. Selektory mogą być przydatne w przypadkach autouzupełniania, ponieważ udostępniają interfejs umożliwiający użytkownikom zmianę wartości pola, w którym są przechowywane dane o dacie lub godzinie. Na przykład w formularzu karty kredytowej selektor daty pozwala użytkownikom wpisać lub zmienić datę ważności karty.

Selektory są oknami, więc nie wyświetlają się w aktywności razem z innymi polami. Aby wyświetlić dane selektora, gdy selektor jest niewidoczny, możesz użyć innego widoku, np. EditText, który może wyświetlić wartość, gdy selektor jest niewidoczny.

Obiekt EditText natywnie oczekuje danych autouzupełniania typu AUTOFILL_TYPE_TEXT. Usługi autouzupełniania zapisują natomiast dane w formacie AUTOFILL_TYPE_DATE, aby utworzyć ich odpowiednią reprezentację. Aby rozwiązać niespójność w typach, zalecamy utworzenie widoku niestandardowego, który dziedziczy wartości z EditText i zaimplementuje metody wymagane do prawidłowej obsługi wartości typu AUTOFILL_TYPE_DATE.

Wykonaj te czynności, aby utworzyć podklasę klasy EditText, która obsługuje wartości typu AUTOFILL_TYPE_DATE:

  1. Utwórz klasę, która dziedziczy dane z elementu EditText.
  2. Zaimplementuj metodę getAutofillType(), która zwraca AUTOFILL_TYPE_DATE.
  3. Zaimplementuj metodę getAutofillValue(), która zwraca obiekt AutofillValue reprezentujący datę w milisekundach. Aby utworzyć zwracany obiekt, użyj metody forDate() w celu wygenerowania obiektu AutofillValue.
  4. Zaimplementuj metodę autofill(). Ta metoda zapewnia logikę obsługi parametru AutofillValue, który jest typu AUTOFILL_TYPE_DATE. Aby obsługiwać parametr, utwórz jego prawidłową reprezentację w postaci ciągu znaków, np. mm/yyyy. Aby ustawić w widoku właściwość text, użyj danych w postaci ciągu znaków.
  5. Zaimplementuj funkcję, która wyświetla selektor, gdy użytkownik chce edytować datę w niestandardowej podklasie EditText. Widok aktualizuje właściwość text, podając ciąg znaków wartość wybranej przez użytkownika w selektorze.

Przykład podklasy EditText obsługującej wartości AUTOFILL_TYPE_DATE znajdziesz w przykładzie platformy autouzupełniania w języku Java lub Kotlin.

Więcej informacji o udowodnieniu, że autouzupełnianie obsługują widoki niestandardowe, znajdziesz w artykule na temat platformy autouzupełniania.