Mostrar caixas de diálogo com um DialogFragment

Um DialogFragment é uma subclasse de fragmento especial projetada para criar e hospedar caixas de diálogo. Embora não seja necessário hospedar a caixa de diálogo em um fragmento, isso permite que a FragmentManager gerencie o estado da caixa de diálogo e a restaure automaticamente quando ocorrer uma mudança de configuração.

Criar um DialogFragment

Para criar um DialogFragment, crie uma classe que estenda DialogFragment e substitua onCreateDialog(), conforme mostrado no exemplo a seguir.

Kotlin

class PurchaseConfirmationDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
            AlertDialog.Builder(requireContext())
                .setMessage(getString(R.string.order_confirmation))
                .setPositiveButton(getString(R.string.ok)) { _,_ -> }
                .create()

    companion object {
        const val TAG = "PurchaseConfirmationDialog"
    }
}

Java

public class PurchaseConfirmationDialogFragment extends DialogFragment {
   @NonNull
   @Override
   public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
       return new AlertDialog.Builder(requireContext())
               .setMessage(getString(R.string.order_confirmation))
               .setPositiveButton(getString(R.string.ok), (dialog, which) -> {} )
               .create();
   }

   public static String TAG = "PurchaseConfirmationDialog";
}

Da mesma forma que onCreateView() cria um View raiz em um fragmento comum, onCreateDialog() cria uma Dialog para mostrar como parte do DialogFragment. O DialogFragment processa a exibição da Dialog nos estados apropriados no ciclo de vida do fragmento.

Assim como acontece com onCreateView(), você pode retornar qualquer subclasse de Dialog de onCreateDialog() e não está limitado ao uso de AlertDialog.

Mostrar o DialogFragment

Não é necessário criar manualmente uma FragmentTransaction para mostrar seu DialogFragment. Em vez disso, use o método show() para exibir a caixa de diálogo. Você pode transmitir uma referência a um FragmentManager e uma String para usar como tag de FragmentTransaction.

Ao criar um DialogFragment dentro de um Fragment, use o FragmentManager filho do fragmento para que o estado seja restaurado corretamente após as mudanças na configuração. Uma tag não nula permite usar findFragmentByTag() para recuperar o DialogFragment mais tarde.

Kotlin

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
PurchaseConfirmationDialogFragment().show(
     childFragmentManager, PurchaseConfirmationDialog.TAG)

Java

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
new PurchaseConfirmationDialogFragment().show(
       getChildFragmentManager(), PurchaseConfirmationDialog.TAG);

Para ter mais controle sobre a FragmentTransaction, é possível usar a sobrecarga show(), que aceita uma FragmentTransaction.

Ciclo de vida do DialogFragment

Um DialogFragment segue o ciclo de vida padrão do fragmento, com alguns callbacks extras. Os mais comuns são os seguintes:

  • onCreateDialog(): substitua esse callback para fornecer um Dialog para o fragmento gerenciar e mostrar.
  • onDismiss(): substitua esse callback se você precisar executar qualquer lógica personalizada quando a Dialog for dispensada, como liberar recursos ou cancelar a inscrição em recursos observáveis.
  • onCancel(): substitua esse callback se precisar executar qualquer lógica personalizada quando a Dialog for cancelada.

O DialogFragment também contém métodos para dispensar ou definir o cancelamento do DialogFragment:

  • dismiss(): dispensa o fragmento e a caixa de diálogo dele. Se o fragmento tiver sido adicionado à backstack, todos os estados dela até a entrada serão exibidos. Caso contrário, uma nova transação será confirmada para remover o fragmento.
  • setCancelable(): controla se a Dialog exibida pode ser cancelada. Use esse método em vez de chamar diretamente Dialog.setCancelable(boolean).

onCreateView() ou onViewCreated() não são substituídos ao usar um DialogFragment com um Dialog. As caixas de diálogo não são apenas visualizações, elas têm uma janela própria. Portanto, não é suficiente substituir onCreateView(). Além disso, onViewCreated() nunca é chamado em um DialogFragment personalizado, a menos que você tenha substituído onCreateView() e fornecido uma visualização não nula.

Usar visualizações personalizadas

Você pode criar um DialogFragment e exibir uma caixa de diálogo substituindo onCreateView(). Você pode atribuir a ele um layoutId, como acontece com um fragmento típico, ou usar o construtor DialogFragment.

A View retornada por onCreateView() é adicionada automaticamente à caixa de diálogo. Na maioria dos casos, isso significa que você não precisa substituir onCreateDialog(), já que a caixa de diálogo vazia padrão é preenchida com a visualização.

Algumas subclasses do DialogFragment, como BottomSheetDialogFragment, incorporam a visualização em uma caixa de diálogo com estilo semelhante ao de uma página inferior.