Android DialogFragment vs Dialog

244

Google recommande que nous utilisions DialogFragmentau lieu d'un simple Dialogen utilisant Fragments API, mais il est absurde d'utiliser un isolé DialogFragmentpour une simple boîte de message de confirmation Oui-Non. Quelle est la meilleure pratique dans ce cas?

skayred
la source
5
En bref, entre autres, simple Dialogou AlertDialog.Builder::create()::show()créera une boîte de dialogue qui disparaît lorsque vous faites pivoter l'écran.
user1032613

Réponses:

83

Oui, utilisez DialogFragmentet onCreateDialogvous pouvez simplement utiliser un générateur AlertDialog pour créer un simple AlertDialogavec des boutons de confirmation Oui / Non. Pas beaucoup de code du tout.

En ce qui concerne la gestion des événements dans votre fragment, il y aurait différentes façons de le faire, mais je définis simplement un message Handlerdans my Fragment, le transmets au DialogFragmentvia son constructeur, puis je retransmets les messages au gestionnaire de mon fragment en fonction des différents événements de clic. Encore une fois, différentes façons de le faire, mais ce qui suit fonctionne pour moi.

Dans la boîte de dialogue, maintenez un message et instanciez-le dans le constructeur:

private Message okMessage;
...
okMessage = handler.obtainMessage(MY_MSG_WHAT, MY_MSG_OK);

Implémentez le onClickListenerdans votre boîte de dialogue, puis appelez le gestionnaire selon le cas:

public void onClick(.....
    if (which == DialogInterface.BUTTON_POSITIVE) {
        final Message toSend = Message.obtain(okMessage);
        toSend.sendToTarget();
    }
 }

Éditer

Et comme il Messageest parcellable, vous pouvez l'enregistrer onSaveInstanceStateet le restaurer

outState.putParcelable("okMessage", okMessage);

Puis dans onCreate

if (savedInstanceState != null) {
    okMessage = savedInstanceState.getParcelable("okMessage");
}
PJL
la source
4
Le problème n'est pas okMessage - le problème est okMessage targetqui sera nul si vous le chargez depuis un bundle. Si la cible d'un Message est nulle et que vous l'utilisez sendToTarget, vous obtiendrez une NullPointerException - non pas parce que le Message est nul, mais parce que sa cible l'est.
hrnt
2
Quels sont les avantages d'utiliser DialogFragment au lieu d'une boîte de dialogue?
Raphael Petegrosso
80
L'avantage d'utiliser un DialogFragment est que tout le cycle de vie de la boîte de dialogue sera géré pour vous. Vous n'obtiendrez plus jamais l'erreur «la boîte de dialogue a fui ...». Accédez à DialogFragment et oubliez les boîtes de dialogue.
Snicolas
6
Je pense que setArguments () et getArguments () devraient être utilisés au lieu de passer okMessage via le constructeur.
pjv
1
Eh bien, j'utilise Builder assez facilement et je gère la gestion des activités avec cet androïde: configChanges = "locale | keyboardHidden | orientation | screenSize" et je ne vois aucun problème dans les applications ...
Renetik
67

Vous pouvez créer des sous-classes DialogFragment génériques comme YesNoDialog et OkDialog, et transmettre le titre et le message si vous utilisez beaucoup de boîtes de dialogue dans votre application.

public class YesNoDialog extends DialogFragment
{
    public static final String ARG_TITLE = "YesNoDialog.Title";
    public static final String ARG_MESSAGE = "YesNoDialog.Message";

    public YesNoDialog()
    {

    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Bundle args = getArguments();
        String title = args.getString(ARG_TITLE);
        String message = args.getString(ARG_MESSAGE);

        return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, null);
                }
            })
            .create();
    }
}

Appelez-le ensuite comme suit:

    DialogFragment dialog = new YesNoDialog();
    Bundle args = new Bundle();
    args.putString(YesNoDialog.ARG_TITLE, title);
    args.putString(YesNoDialog.ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(this, YES_NO_CALL);
    dialog.show(getFragmentManager(), "tag");

Et gérez le résultat onActivityResult.

ashishduh
la source
Oui, DialogFragment gère tous les événements du cycle de vie pour vous.
ashishduh
1
Je pense que ce n'est pas le cas, car après la rotation, l'ancien dialogue existe toujours et il reste assigné à l'ancien fragment non existant (dialog.setTargetFragment (this, YES_NO_CALL);) donc après la rotation, getTargetFragment (). OnActivityResult ne fonctionne pas
Malachiasz
7
quels sont YES_NO_CALL, getFragmentManager()et onActivityResult?
msysmilu
2
YES_NO_CALLest un int personnalisé qui est le code de demande. getFragmentManager()obtient le gestionnaire de fragments pour l'activité et onActivityResult()est une méthode de rappel de cycle de vie de fragment.
ashishduh
3
Remplacez getFragmentManager () par getSupportFragmentManager ();
Avinash Verma
33

Utilisez DialogFragment sur AlertDialog:


  • Depuis l'introduction de l'API niveau 13 :

    la méthode showDialog de Activity est déconseillée . Il n'est pas conseillé d'invoquer une boîte de dialogue ailleurs dans le code car vous devrez gérer la boîte de dialogue vous-même (par exemple, changement d'orientation).

  • Dialogue de différence - Fragment - AlertDialog

    Sont-ils tellement différents? De la référence Android concernant DialogFragment :

    Un DialogFragment est un fragment qui affiche une fenêtre de dialogue, flottant au-dessus de la fenêtre de son activité. Ce fragment contient un objet Dialog, qu'il affiche comme approprié en fonction de l'état du fragment. Le contrôle de la boîte de dialogue (décider quand l'afficher, la masquer, la fermer) doit être fait via l'API ici , pas avec des appels directs sur la boîte de dialogue.

  • Autres notes

    • Les fragments sont une évolution naturelle dans le cadre Android en raison de la diversité des appareils avec différentes tailles d'écran.
    • DialogFragments and Fragments sont disponibles dans la bibliothèque de support, ce qui rend la classe utilisable dans toutes les versions actuelles d'Android.
Tobrun
la source
28

Je recommanderais d'utiliser DialogFragment.

Bien sûr, la création d'une boîte de dialogue "Oui / Non" avec elle est assez complexe étant donné que cela devrait être une tâche plutôt simple, mais la création d'une boîte de dialogue similaire avec Dialogest également étonnamment compliquée.

(Le cycle de vie des activités complique les choses - vous devez laisser Activitygérer le cycle de vie de la boîte de dialogue - et il n'y a aucun moyen de transmettre des paramètres personnalisés, par exemple le message personnalisé, Activity.showDialogsi vous utilisez des niveaux d'API inférieurs à 8)

La bonne chose est que vous pouvez généralement construire votre propre abstraction par dessus DialogFragmentassez facilement.

hrnt
la source
Comment gérerez-vous les rappels des dialogues d'alerte (oui, non)?
Alexey Zakharov
La manière la plus simple serait d'implémenter une méthode dans l'activité d'hébergement qui prend un Stringparamètre. Lorsque l'utilisateur clique sur "Oui", par exemple, la boîte de dialogue appelle la méthode de l'activité avec le paramètre "d'accord". Ces paramètres sont spécifiés lors de l'affichage de la boîte de dialogue, par exemple AskDialog.ask ("Êtes-vous d'accord avec ces termes?", "D'accord", "en désaccord");
2011
5
Mais j'ai besoin d'un rappel à l'intérieur du fragment, pas d'une activité. Je peux utiliser setTargetFragment et le convertir en interface. Mais c'est l'enfer.
Alexey Zakharov
Vous pouvez également récupérer le fragment cible en définissant une balise sur la cible et en utilisant FragmentManager's findFragmentByTag. Mais oui, cela nécessite un peu de code.
hrnt
@AlexeyZakharov Je sais que c'est environ 5 ans de retard mais vous pouvez passer le Fragment this et avoir votre Activity extendsvotre Interface. Attention au threading cependant, vous pouvez sauter des appels d'interface lorsque vous n'en voulez pas nécessairement si votre concurrence n'est pas en échec. Vous n'êtes pas sûr de ce que cela fait avec la mémoire et les spaghettis de dépendance circulaire, est-ce que quelqu'un d'autre aimerait jouer? L'autre option est Message/ Handlermais vous pouvez toujours rencontrer des problèmes de concurrence.
tricknology
8

Generic AlertDialogFragment avec Builder Pattern

Dans mon projet, j'en utilisais AlertDialog.Builderdéjà déjà beaucoup avant de découvrir que c'était problématique. Cependant, je ne voulais pas changer autant de code n'importe où dans mon application. De plus, je suis en fait un fan de passer OnClickListenersen classes anonymes là où elles sont nécessaires (c'est-à-dire lors de l'utilisation setPositiveButton(), setNegativeButton()etc.) au lieu d'avoir à implémenter des milliers de méthodes de rappel pour communiquer entre un fragment de dialogue et le fragment de support, ce qui peut, dans à mon avis, conduire à un code très déroutant et complexe. Surtout, si vous avez plusieurs boîtes de dialogue différentes dans un fragment et que vous devez ensuite distinguer dans les implémentations de rappel quelle boîte de dialogue est actuellement affichée.

Par conséquent, j'ai combiné différentes approches pour créer une AlertDialogFragmentclasse d'assistance générique qui peut être utilisée exactement comme AlertDialog :


SOLUTION

( VEUILLEZ NOTER que j'utilise des expressions lambda Java 8 dans mon code, vous devrez donc peut-être modifier des parties du code si vous n'utilisez pas encore d' expressions lambda .)

/**
 * Helper class for dialog fragments to show a {@link AlertDialog}. It can be used almost exactly
 * like a {@link AlertDialog.Builder}
 * <p />
 * Creation Date: 22.03.16
 *
 * @author felix, http://flx-apps.com/
 */
public class AlertDialogFragment extends DialogFragment {
    protected FragmentActivity activity;
    protected Bundle args;
    protected String tag = AlertDialogFragment.class.getSimpleName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = getActivity();
        args = getArguments();
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = setDialogDefaults(new AlertDialog.Builder(getActivity())).create();

        if (args.containsKey("gravity")) {
            dialog.getWindow().getAttributes().gravity = args.getInt("gravity");
        }

        dialog.setOnShowListener(d -> {
            if (dialog != null && dialog.findViewById((android.R.id.message)) != null) {
                ((TextView) dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
            }
        });
        return dialog;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);

        if (args.containsKey("onDismissListener")) {
            Parcelable onDismissListener = args.getParcelable("onDismissListener");
            if (onDismissListener != null && onDismissListener instanceof ParcelableOnDismissListener) {
                ((ParcelableOnDismissListener) onDismissListener).onDismiss(this);
            }
        }
    }

    /**
     * Sets default dialog properties by arguments which were set using {@link #builder(FragmentActivity)}
     */
    protected AlertDialog.Builder setDialogDefaults(AlertDialog.Builder builder) {
        args = getArguments();
        activity = getActivity();

        if (args.containsKey("title")) {
            builder.setTitle(args.getCharSequence("title"));
        }

        if (args.containsKey("message")) {
            CharSequence message = args.getCharSequence("message");
            builder.setMessage(message);
        }

        if (args.containsKey("viewId")) {
            builder.setView(getActivity().getLayoutInflater().inflate(args.getInt("viewId"), null));
        }

        if (args.containsKey("positiveButtonText")) {
            builder.setPositiveButton(args.getCharSequence("positiveButtonText"), (dialog, which) -> {
                onButtonClicked("positiveButtonListener", which);
            });
        }

        if (args.containsKey("negativeButtonText")) {
            builder.setNegativeButton(args.getCharSequence("negativeButtonText"), (dialog, which) -> {
                onButtonClicked("negativeButtonListener", which);
            });
        }

        if (args.containsKey("neutralButtonText")) {
            builder.setNeutralButton(args.getCharSequence("neutralButtonText"), (dialog, which) -> {
                onButtonClicked("neutralButtonListener", which);
            });
        }

        if (args.containsKey("items")) {
            builder.setItems(args.getStringArray("items"), (dialog, which) -> {
                onButtonClicked("itemClickListener", which);
            });
        }

        // @formatter:off
        // FIXME this a pretty hacky workaround: we don't want to show the dialog if onClickListener of one of the dialog's button click listener were lost
        //       the problem is, that there is no (known) solution for parceling a OnClickListener in the long term (only for state changes like orientation change,
        //       but not if the Activity was completely lost)
        if (
                (args.getParcelable("positiveButtonListener") != null && !(args.getParcelable("positiveButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("negativeButtonListener") != null && !(args.getParcelable("negativeButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("neutralButtonListener") != null && !(args.getParcelable("neutralButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("itemClickListener") != null && !(args.getParcelable("itemClickListener") instanceof ParcelableOnClickListener))
        ) {
            new DebugMessage("Forgot onClickListener. Needs to be dismissed.")
                    .logLevel(DebugMessage.LogLevel.VERBOSE)
                    .show();
            try {
                dismissAllowingStateLoss();
            } catch (NullPointerException | IllegalStateException ignored) {}
        }
        // @formatter:on

        return builder;
    }

    public interface OnDismissListener {
        void onDismiss(AlertDialogFragment dialogFragment);
    }

    public interface OnClickListener {
        void onClick(AlertDialogFragment dialogFragment, int which);
    }

    protected void onButtonClicked(String buttonKey, int which) {
        ParcelableOnClickListener parcelableOnClickListener = getArguments().getParcelable(buttonKey);
        if (parcelableOnClickListener != null) {
            parcelableOnClickListener.onClick(this, which);
        }
    }

    // region Convenience Builder Pattern class almost similar to AlertDialog.Builder
    // =============================================================================================

    public AlertDialogFragment builder(FragmentActivity activity) {
        this.activity = activity;
        this.args = new Bundle();
        return this;
    }

    public AlertDialogFragment addArguments(Bundle bundle) {
        args.putAll(bundle);
        return this;
    }

    public AlertDialogFragment setTitle(int titleStringId) {
        return setTitle(activity.getString(titleStringId));
    }

    public AlertDialogFragment setTitle(CharSequence title) {
        args.putCharSequence("title", title);
        return this;
    }

    public AlertDialogFragment setMessage(int messageStringId) {
        return setMessage(activity.getString(messageStringId));
    }

    public AlertDialogFragment setMessage(CharSequence message) {
        args.putCharSequence("message", message);
        return this;
    }

    public AlertDialogFragment setPositiveButton(int textStringId, OnClickListener onClickListener) {
        return setPositiveButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setPositiveButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("positiveButtonText", text);
        args.putParcelable("positiveButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNegativeButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNegativeButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNegativeButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("negativeButtonText", text);
        args.putParcelable("negativeButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNeutralButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNeutralButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNeutralButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("neutralButtonText", text);
        args.putParcelable("neutralButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setOnDismissListener(OnDismissListener onDismissListener) {
        if (onDismissListener == null) {
            return this;
        }

        Parcelable p = new ParcelableOnDismissListener() {
            @Override
            public void onDismiss(AlertDialogFragment dialogFragment) {
                onDismissListener.onDismiss(dialogFragment);
            }
        };
        args.putParcelable("onDismissListener", p);
        return this;
    }

    public AlertDialogFragment setItems(String[] items, AlertDialogFragment.OnClickListener onClickListener) {
        args.putStringArray("items", items);
        args.putParcelable("itemClickListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setView(int viewId) {
        args.putInt("viewId", viewId);
        return this;
    }

    public AlertDialogFragment setGravity(int gravity) {
        args.putInt("gravity", gravity);
        return this;
    }

    public AlertDialogFragment setTag(String tag) {
        this.tag = tag;
        return this;
    }

    public AlertDialogFragment create() {
        setArguments(args);
        return AlertDialogFragment.this;
    }

    public AlertDialogFragment show() {
        create();
        try {
            super.show(activity.getSupportFragmentManager(), tag);
        }
        catch (IllegalStateException e1) {

            /**
             * this whole part is used in order to attempt to show the dialog if an
             * {@link IllegalStateException} was thrown (it's kinda comparable to
             * {@link FragmentTransaction#commitAllowingStateLoss()} 
             * So you can remove all those dirty hacks if you are sure that you are always
             * properly showing dialogs in the right moments
             */

            new DebugMessage("got IllegalStateException attempting to show dialog. trying to hack around.")
                    .logLevel(DebugMessage.LogLevel.WARN)
                    .exception(e1)
                    .show();

            try {
                Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
                mShownByMe.setAccessible(true);
                mShownByMe.set(this, true);
                Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
                mDismissed.setAccessible(true);
                mDismissed.set(this, false);
            }
            catch (Exception e2) {
                new DebugMessage("error while showing dialog")
                        .exception(e2)
                        .logLevel(DebugMessage.LogLevel.ERROR)
                        .show();
            }
            FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
            transaction.add(this, tag);
            transaction.commitAllowingStateLoss(); // FIXME hacky and unpredictable workaround
        }
        return AlertDialogFragment.this;
    }

    @Override
    public int show(FragmentTransaction transaction, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    @Override
    public void show(FragmentManager manager, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    protected ParcelableOnClickListener createParcelableOnClickListener(AlertDialogFragment.OnClickListener onClickListener) {
        if (onClickListener == null) {
            return null;
        }

        return new ParcelableOnClickListener() {
            @Override
            public void onClick(AlertDialogFragment dialogFragment, int which) {
                onClickListener.onClick(dialogFragment, which);
            }
        };
    }

    /**
     * Parcelable OnClickListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnClickListener extends ResultReceiver implements AlertDialogFragment.OnClickListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnClickListener() {
            super(null);
        }

        @Override
        public abstract void onClick(AlertDialogFragment dialogFragment, int which);
    }

    /**
     * Parcelable OnDismissListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnDismissListener extends ResultReceiver implements AlertDialogFragment.OnDismissListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnDismissListener() {
            super(null);
        }

        @Override
        public abstract void onDismiss(AlertDialogFragment dialogFragment);
    }


    // =============================================================================================
    // endregion
}

USAGE

// showing a normal alert dialog with state loss on configuration changes (like device rotation)
new AlertDialog.Builder(getActivity())
        .setTitle("Are you sure? (1)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

// showing a dialog fragment using the helper class with no state loss on configuration changes
new AlertDialogFragment.builder(getActivity())
        .setTitle("Are you sure? (2)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

Je poste ceci ici non seulement pour partager ma solution, mais aussi parce que je voulais vous demander votre opinion: cette approche est-elle légitime ou problématique dans une certaine mesure?

flxapps
la source
3
C'est une idée très intéressante, mais je ne pense pas que la conception de l'API fonctionne. Si vous passez un OnClickListener à setPositiveButton (), lorsque le périphérique est tourné et que le fragment est recréé à partir des arguments du bundle, les OnClickListeners ne seront pas correctement recréés à partir de la parcelle. Le problème fondamental est que vous ne pouvez pas recréer un écouteur pendant la rotation, mais l'interface API (qui prend les interfaces) l'exige. Je souhaite que ce ne soit pas le cas (car j'aime l'idée).
Xargs
1
Belle idée, mais comme le dit @Xargs, cela ne fonctionne pas. Les écouteurs transmis ne sont pas recréés correctement lors de la rotation.
Graham Borland
Mes résultats sont que cela fonctionne réellement sur la rotation et sur la reprise de l'application (après être allé à l'écran d'accueil par exemple), mais pas lorsque l'activité est restaurée après avoir été complètement détruite (alors les OnClickListeners sont en effet perdus). (Testé sur Android 4.4.4 et Android 5.1.1)
flxapps
Je n'ai pas testé cette implémentation exacte mais d'après ce que j'ai testé, un écouteur parcelable passé à un paquet de fragments est appelé correctement lors de la recréation. Je ne sais pas pourquoi mais cela semble fonctionner.
Saad Farooq
@flxapps, en cas de vue personnalisée, comment obtenir les vues enfant et modifier leurs propriétés ou appliquer des écouteurs? Dans votre classe, vous ne renvoyez aucune instance de dialogue et cela pourrait provoquer une exception si quelqu'un essaie d'obtenir des vues d'enfant
Zubair Rehman
5

Puis-je suggérer une petite simplification de la réponse de @ ashishduh:

public class AlertDialogFragment extends DialogFragment {
public static final String ARG_TITLE = "AlertDialog.Title";
public static final String ARG_MESSAGE = "AlertDialog.Message";

public static void showAlert(String title, String message, Fragment targetFragment) {
    DialogFragment dialog = new AlertDialogFragment();
    Bundle args = new Bundle();
    args.putString(ARG_TITLE, title);
    args.putString(ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(targetFragment, 0);
    dialog.show(targetFragment.getFragmentManager(), "tag");
}

public AlertDialogFragment() {}

@NonNull
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState)
{
    Bundle args = getArguments();
    String title = args.getString(ARG_TITLE, "");
    String message = args.getString(ARG_MESSAGE, "");

    return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .create();
}

Il supprime la nécessité pour l'utilisateur (de la classe) de se familiariser avec les composants internes du composant et rend l'utilisation très simple:

AlertDialogFragment.showAlert(title, message, this);

PS Dans mon cas, j'avais besoin d'une simple boîte de dialogue d'alerte, c'est donc ce que j'ai créé. Vous pouvez appliquer l'approche à un type Oui / Non ou à tout autre type dont vous avez besoin.

HACHE
la source
1

Utilisez Dialogue pour des dialogues simples oui ou non.

Lorsque vous avez besoin de vues plus complexes dans lesquelles vous devez vous procurer le cycle de vie, comme oncreate, demander des autorisations, tout remplacement de cycle de vie, j'utiliserais un fragment de dialogue. Ainsi, vous séparez les autorisations et tout autre code dont la boîte de dialogue a besoin pour fonctionner sans avoir à communiquer avec l'activité d'appel.

Gustavo Baiocchi Costa
la source