Seletores

O Android oferece controles para que o usuário selecione um horário ou selecione uma data como caixas de diálogo prontas para uso. Cada seletor fornece controles para selecionar cada parte do horário (hora, minuto, período do dia) ou data (dia, mês, ano). O uso desses seletores ajuda a garantir que os usuários possam escolher um horário ou data válido, com o formato correto e ajustado para a localidade do usuário.

Recomendamos que você use DialogFragment para hospedar cada seletor de horário ou data. O DialogFragment gerencia o ciclo de vida da caixa de diálogo e permite exibir os seletores em diferentes configurações de layout, como uma caixa de diálogo básica em dispositivos móveis ou uma parte incorporada do layout em telas grandes.

Embora DialogFragment tenha sido adicionado pela primeira vez à plataforma no Android 3.0 (API de nível 11), caso seu app seja compatível com versões anteriores (até mesmo a versão 1.6 do Android), você poderá usar a classe DialogFragment, disponível na Biblioteca de Suporte, para oferecer compatibilidade com versões anteriores.

Observação: as amostras de código abaixo mostram como criar caixas de diálogo para um seletor de horário e um seletor de data usando as APIs da Biblioteca de Suporte para DialogFragment. Se a minSdkVersion do app for 11 ou mais recente, você poderá usar a versão de plataforma de DialogFragment.

As principais classes são as seguintes:

Consulte também a Visão geral de fragmentos.

Criar um seletor de horário

Para exibir um TimePickerDialog usando DialogFragment, é necessário definir uma classe de fragmento que estenda DialogFragment e retorne um TimePickerDialog do método onCreateDialog() do fragmento.

Observação: se o app for compatível com versões do Android anteriores à versão 3.0, configure seu projeto do Android com a Biblioteca de Suporte, conforme descrito em Configurar um projeto para usar uma biblioteca.

Estender o DialogFragment para um seletor de horário

Para definir um DialogFragment para um TimePickerDialog, você precisa:

Veja um exemplo:

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 chosen by the user
    }
}

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 chosen by the user
    }
}

Consulte a classe TimePickerDialog para ver informações sobre os argumentos do construtor.

Agora, você só precisa de um evento que adicione uma instância desse fragmento à sua atividade.

Mostrar o seletor de horário

Depois de definir um DialogFragment como o mostrado acima, você pode exibir o seletor de horário criando uma instância de DialogFragment e chamando show().

Por exemplo, veja um botão que, quando clicado, chama um método para mostrar a caixa de diálogo:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_time"
    android:onClick="showTimePickerDialog" />

Quando o usuário clica nesse botão, o sistema chama o seguinte método:

Kotlin

fun showTimePickerDialog(v: View) {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Java

public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(getSupportFragmentManager(), "timePicker");
}

Esse método chama show() em uma nova instância de DialogFragment definida acima. O método show() precisa de uma instância de FragmentManager e um nome de tag exclusivo para o fragmento.

Cuidado: caso seu app seja compatível com versões do Android anteriores à 3.0, chame getSupportFragmentManager() para adquirir uma instância de FragmentManager. Verifique também se a sua atividade que exibe o seletor de horário estende FragmentActivity em vez da classe Activity padrão.

Criar um seletor de datas

Criar um DatePickerDialog é como criar um TimePickerDialog. A única diferença é a caixa de diálogo criada para o fragmento.

Para exibir um DatePickerDialog usando DialogFragment, é necessário definir uma classe de fragmento que estenda DialogFragment e retorne um DatePickerDialog do método onCreateDialog() do fragmento.

Estender DialogFragment para um seletor de datas

Para definir um DialogFragment para um DatePickerDialog, você precisa:

Veja um exemplo:

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(activity, this, year, month, day)
    }

    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        // Do something with the date chosen by the user
    }
}

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(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // Do something with the date chosen by the user
    }
}

Consulte a classe DatePickerDialog para ver informações sobre os argumentos do construtor.

Agora, você só precisa de um evento que adicione uma instância desse fragmento à sua atividade.

Mostrar o seletor de datas

Depois de definir um DialogFragment como o mostrado acima, você pode exibir o seletor de datas criando uma instância de DialogFragment e chamando show().

Por exemplo, veja um botão que, quando clicado, chama um método para mostrar a caixa de diálogo:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_date"
    android:onClick="showDatePickerDialog" />

Quando o usuário clica nesse botão, o sistema chama o seguinte método:

Kotlin

fun showDatePickerDialog(v: View) {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Java

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getSupportFragmentManager(), "datePicker");
}

Esse método chama show() em uma nova instância de DialogFragment definida acima. O método show() precisa de uma instância de FragmentManager e um nome de tag exclusivo para o fragmento.

Usar seletores com o preenchimento automático

O Android 8.0 introduz a Estrutura de preenchimento automático, que permite que os usuários salvem dados que podem ser usados posteriormente para preencher formulários em diferentes apps. Os seletores podem ser úteis em algumas situações de preenchimento automático, fornecendo uma IU que permite que os usuários mudem o valor de um campo que armazena dados de data ou horário. Por exemplo, em um formulário de cartão de crédito, um seletor de data permite que os usuários insiram ou mudem a data de validade do cartão.

Como os seletores são caixas de diálogo, eles não são exibidos em uma atividade junto com outros campos. Para exibir os dados do seletor quando ele não estiver visível, você pode usar outra visualização, como EditText, que pode exibir o valor quando o seletor não estiver visível.

De maneira nativa, um objeto EditText espera dados de preenchimento automático do tipo AUTOFILL_TYPE_TEXT. Em contrapartida, os serviços de preenchimento automático salvam os dados como AUTOFILL_TYPE_DATE, para que seja possível criar uma representação adequada. Para solucionar a inconsistência nos tipos, é recomendado criar uma visualização personalizada herdada de EditText que implemente os métodos exigidos para processar corretamente os valores do tipo AUTOFILL_TYPE_DATE.

Siga as etapas a seguir para criar uma subclasse de EditText que possa processar valores do tipo AUTOFILL_TYPE_DATE:

  1. Crie uma classe herdada de EditText.
  2. Implemente o método getAutofillType(), que precisa retornar AUTOFILL_TYPE_DATE.
  3. Implemente o método getAutofillValue(), que precisa retornar um objeto AutofillValue que represente a data em milissegundos. Para criar o objeto de retorno, use o método forDate() para gerar um objeto AutofillValue.
  4. Implemente o método autofill(). Esse método fornece a lógica para manipular o parâmetro AutofillValue, que é do tipo AUTOFILL_TYPE_DATE. Para manipular o parâmetro, crie uma representação de string adequada, como mm/yyyy. Use a representação de string para definir a propriedade text da visualização.
  5. Implemente a funcionalidade que exibe um seletor quando o usuário quer editar a data na subclasse personalizada de EditText. A visualização precisa atualizar a propriedade text com uma representação de string do valor que o usuário escolheu no seletor.

Para ver um exemplo de uma subclasse de EditText que processa valores AUTOFILL_TYPE_DATE, consulte a amostra de Estrutura de preenchimento automático Java | Kotlin (links em inglês).

Para saber mais sobre como oferecer compatibilidade com o preenchimento automático para visualizações personalizadas, consulte Compatibilidade com visualizações personalizadas.