Dodaj selektory do swojej aplikacji

Wypróbuj tworzenie wiadomości
Jetpack Compose to zalecany zestaw narzędzi UI na Androida. Dowiedz się, jak dodawać komponenty w sekcji Tworzenie.

Android udostępnia użytkownikowi elementy sterujące, które umożliwiają wybór czasu lub daty w gotowych oknach dialogowych. Te elementy selektora umożliwiają wybór poszczególnych części czasu (godzina, minuta, AM/PM) lub daty (miesiąc, dzień, rok).

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

Dzięki tym selektorom użytkownicy mogą wybrać prawidłowy, poprawnie sformatowany czas lub datę dostosowaną do ich lokalizacji.

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

Zalecamy używanie DialogFragment do hostowania każdego selektora czasu lub daty. DialogFragment zarządza cyklem życia okna i pozwala wyświetlać selektory w różnych konfiguracjach układu, np. w podstawowym oknie dialogowym w telefonie lub jako część układu na dużych ekranach.

Utwórz selektor godziny

Aby wyświetlić element TimePickerDialog za pomocą elementu DialogFragment, zdefiniuj klasę fragmentu, która rozszerza klasę DialogFragment, i zwraca element TimePickerDialog z metody onCreateDialog() fragmentu.

Rozszerz fragment DialogFragment dla selektora czasu

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

  • Zdefiniuj metodę onCreateDialog(), aby zwrócić instancję typu TimePickerDialog.
  • Zaimplementuj interfejs TimePickerDialog.OnTimeSetListener, aby otrzymywać wywołania zwrotne, gdy użytkownik ustawia czas.

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.

Potrzebne jest teraz zdarzenie, które doda wystąpienie tego fragmentu do Twojej aktywności.

Pokaż selektor godziny

Po zdefiniowaniu klasy DialogFragment, takiej jak w poprzednim przykładzie, możesz wyświetlić selektor czasu, tworząc instancję klasy DialogFragment i wywołując metodę show().

Oto przykład przycisku, który po kliknięciu wywołuje metodę wyświetlania okna dialogowego:

<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 tę 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 show() w nowej instancji funkcji DialogFragment zdefiniowanej w poprzednim przykładzie. Metoda show() wymaga wystąpienia FragmentManager oraz unikalnej nazwy tagu dla fragmentu.

Tworzenie selektora daty

Tworzenie DatePickerDialog jest jak tworzenie TimePickerDialog. Różnica polega na tym, że dialog jest tworzony dla fragmentu.

Aby wyświetlić element DatePickerDialog za pomocą elementu DialogFragment, zdefiniuj klasę fragmentu, która rozszerza klasę DialogFragment, i zwraca element DatePickerDialog z metody onCreateDialog() tego fragmentu.

Rozszerz fragment DialogFragment na potrzeby selektora daty

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

  • Określ metodę onCreateDialog(), która zwraca instancję DatePickerDialog.
  • Zaimplementuj interfejs DatePickerDialog.OnDateSetListener, aby odbierać wywołanie zwrotne, gdy użytkownik ustawi datę.

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.

Wystarczy, że dodasz do swojej aktywności zdarzenie, które dodaje wystąpienie tego fragmentu.

Pokaż selektor dat

Po zdefiniowaniu obiektu DialogFragment w taki sposób jak w poprzednim przykładzie możesz wyświetlić selektor daty, tworząc instancję obiektu DialogFragment i wywołując metodę show().

Oto przykładowy przycisk, który po kliknięciu wywołuje metodę wyświetlenia okna:

<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 tę 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 nowej instancji obiektu DialogFragment zdefiniowanego w poprzednim przykładzie. Metoda show() wymaga wystąpienia FragmentManager oraz niepowtarzalnej nazwy tagu dla fragmentu.

Korzystanie z selektorów w przypadku autouzupełniania

W 2017 r. wprowadziliśmy na Androidzie mechanizm autouzupełniania, który pozwala użytkownikom zapisywać dane, których mogą używać do wypełniania formularzy w różnych aplikacjach. Selektory mogą być przydatne w scenariuszach autouzupełniania, ponieważ zapewniają interfejs, który pozwala użytkownikom zmieniać wartość pola przechowującego dane o dacie lub czasie. Na przykład w formularzu karty kredytowej selektor daty umożliwia użytkownikowi wpisanie lub zmianę daty ważności karty.

Selektory to okna, więc nie są wyświetlane w aktywności razem z innymi polami. Aby wyświetlić dane selektora, gdy selektor nie jest widoczny, możesz użyć innego widoku, takiego jak EditText, który może wyświetlać wartość, gdy selektor nie jest widoczny.

Obiekt EditText domyślnie oczekuje danych autouzupełniania typu AUTOFILL_TYPE_TEXT. Usługi autouzupełniania zapisują natomiast dane jako AUTOFILL_TYPE_DATE, aby je odpowiednio przedstawić. Aby rozwiązać problem niespójności typów, utwórz widok niestandardowy, który dziedziczy z poziomu EditText i implementuje metody wymagane do prawidłowego obsługiwania wartości typu AUTOFILL_TYPE_DATE.

Aby utworzyć podklasę typu EditText, która może obsługiwać wartości typu AUTOFILL_TYPE_DATE:

  1. Utwórz klasę dziedziczącą z 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ć obiekt zwracany, użyj metody forDate() do 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 odpowiedni ciąg znaków, np. mm/yyyy. Użyj reprezentacji ciągu znaków, aby ustawić właściwość text widoku.
  5. Wprowadź funkcję, która wyświetla selektor, gdy użytkownik chce edytować datę w niestandardowej podklasie EditText. Widok aktualizuje właściwość text o wartość, którą użytkownik wybiera w selektorze, w formie ciągu znaków.

Przykład podklasy EditText, która obsługuje wartości AUTOFILL_TYPE_DATE, znajdziesz w pliku Autofill Framework w Java lub Kotlin.

Więcej informacji o obsługiwaniu autouzupełniania w widokach niestandardowych znajdziesz w artykule Usługa autouzupełniania.