Definitivamente, a melhor abordagem é usar DialogFragment.
Aqui está minha solução de classe wrapper que ajuda a evitar que diferentes diálogos sejam descartados dentro de um Fragment (ou Activity com pequena refatoração). Além disso, ajuda a evitar a refatoração massiva de código se, por alguns motivos, houver muitos dados AlertDialogs
espalhados no código, com pequenas diferenças entre eles em termos de ações, aparência ou outra coisa.
public class DialogWrapper extends DialogFragment {
private static final String ARG_DIALOG_ID = "ARG_DIALOG_ID";
private int mDialogId;
/**
* Display dialog fragment.
* @param invoker The fragment which will serve as {@link AlertDialog} alert dialog provider
* @param dialogId The ID of dialog that should be shown
*/
public static <T extends Fragment & DialogProvider> void show(T invoker, int dialogId) {
Bundle args = new Bundle();
args.putInt(ARG_DIALOG_ID, dialogId);
DialogWrapper dialogWrapper = new DialogWrapper();
dialogWrapper.setArguments(args);
dialogWrapper.setTargetFragment(invoker, 0);
dialogWrapper.show(invoker.getActivity().getSupportFragmentManager(), null);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDialogId = getArguments().getInt(ARG_DIALOG_ID);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return getDialogProvider().getDialog(mDialogId);
}
private DialogProvider getDialogProvider() {
return (DialogProvider) getTargetFragment();
}
public interface DialogProvider {
Dialog getDialog(int dialogId);
}
}
Quando se trata de Activity, você pode invocar getContext()
dentro onCreateDialog()
, lançar para a DialogProvider
interface e solicitar um diálogo específico por mDialogId
. Toda lógica para lidar com um fragmento de destino deve ser excluída.
Uso do fragmento:
public class MainFragment extends Fragment implements DialogWrapper.DialogProvider {
private static final int ID_CONFIRMATION_DIALOG = 0;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
Button btnHello = (Button) view.findViewById(R.id.btnConfirm);
btnHello.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogWrapper.show(MainFragment.this, ID_CONFIRMATION_DIALOG);
}
});
}
@Override
public Dialog getDialog(int dialogId) {
switch (dialogId) {
case ID_CONFIRMATION_DIALOG:
return createConfirmationDialog(); //Your AlertDialog
default:
throw new IllegalArgumentException("Unknown dialog id: " + dialogId);
}
}
}
Você pode ler o artigo completo no meu blog. Como evitar que o Dialog seja descartado? e brincar com o código-fonte .