web-dev-qa-db-fra.com

Fragment de dialogue oui / non le plus simple

Je voudrais faire un dialog fragment qui demande "Êtes-vous sûr?" avec une réponse "oui/non".

J'ai regardé la documentation et c'est vraiment bavard, allant partout, expliquant comment créer des boîtes de dialogue avancées, mais pas de code intact pour créer une sorte de boîte de dialogue simple `` hello world ''. La plupart des didacticiels utilisent le système de boîte de dialogue obsolète. Le blog officiel semble être inutilement compliqué et difficile à comprendre.

Alors, quelle est la façon la plus simple de créer et d'afficher une boîte de dialogue d'alerte vraiment basique? Points bonus s'il utilise la bibliothèque de support.

39
Muz

Un DialogFragment est vraiment juste un fragment qui enveloppe une boîte de dialogue. Vous pouvez y placer tout type de boîte de dialogue en créant et en renvoyant la boîte de dialogue dans la méthode onCreateDialog () du DialogFragment.

Voici un exemple de DialogFragment:

class MyDialogFragment extends DialogFragment{
    Context mContext;
    public MyDialogFragment() {
        mContext = getActivity();
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
        alertDialogBuilder.setTitle("Really?");
        alertDialogBuilder.setMessage("Are you sure?");
        //null should be your on click listener
        alertDialogBuilder.setPositiveButton("OK", null);
        alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });


        return alertDialogBuilder.create();
    }
}

Pour créer l'appel de dialogue:

new MyDialogFragment().show(getFragmentManager(), "MyDialog");

Et pour fermer la boîte de dialogue quelque part:

((MyDialogFragment)getFragmentManager().findFragmentByTag("MyDialog")).getDialog().dismiss();

Tout ce code fonctionnera parfaitement avec la bibliothèque de support, en changeant simplement les importations pour utiliser les classes de la bibliothèque de support.

78
athor

Alors, quelle est la façon la plus simple de créer et d'afficher une boîte de dialogue d'alerte vraiment basique? Points bonus s'il utilise la bibliothèque de support.

Créez simplement un DialogFragment (SDK ou bibliothèque de support) et remplacez sa méthode onCreateDialog pour renvoyer un AlertDialog avec le texte et les boutons désirés:

public static class SimpleDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setMessage("Are you sure?")
                .setPositiveButton("Ok", null)
                .setNegativeButton("No way", null)
                .create();
    }

}

Pour faire quelque chose lorsque l'utilisateur utilise l'un des boutons, vous devrez fournir une instance d'un DialogInterface.OnClickListener au lieu des références null de mon code.

12
Luksprog

Pour ceux qui codent avec Kotlin et Anko , vous pouvez maintenant faire des dialogues en 4 lignes de code:

alert("Order", "Do you want to order this item?") {
    positiveButton("Yes") { processAnOrder() }
    negativeButton("No") { }
}.show()
5
Muz

en raison du cycle de vie de l'activité/du fragment L'approche @ athor et @lugsprog peut échouer, , la méthode la plus élégante consiste à ** obtenir le contexte d'activité de la méthode onAttach et à le stocker en tant que référence faible ** (& essayez d'éviter le constructeur non par défaut dans DialogFragment !, pour passer n'importe quel argument aux dialogues utiliser des arguments) comme ceci:

public class NotReadyDialogFragment extends DialogFragment {

    public static String DIALOG_ARGUMENTS = "not_ready_dialog_fragment_arguments";

    private WeakReference<Context> _contextRef;

    public NotReadyDialogFragment() {
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        /** example pulling of arguments */
        Bundle bundle = getArguments();
        if (bundle!=null) {
            bundle.get(DIALOG_ARGUMENTS);
        }

        //
        // Caution !!!
        // check we can use contex - by call to isAttached 
        // or by checking stored weak reference value itself is not null 
        // or stored in context -> example allowCreateDialog() 
        // - then for example you could throw illegal state exception or return null 
        //
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(_contextRef.get());
        alertDialogBuilder.setMessage("...");
        alertDialogBuilder.setNegativeButton("Przerwij", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        return alertDialogBuilder.create();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        _contextRef = new WeakReference<Context>(activity);
    }

     boolean allowCreateDialog() {
         return _contextRef !== null 
                && _contextRef.get() != null;
     }

EDIT: & Si vous voulez fermer la boîte de dialogue alors:

  1. essayez de l'obtenir
  2. vérifier s'il existe
  3. vérifier si ça se voit
  4. rejeter

quelque chose comme ça :

        NotReadyDialogFragment dialog = ((NotReadyDialogFragment) getActivity().getFragmentManager().findFragmentByTag("MyDialogTag"));
    if (dialog != null) {
        Dialog df = dialog.getDialog();
        if (df != null && df.isShowing()) {
            df.dismiss();
        }
    }

EDIT2: & si vous voulez définir la boîte de dialogue comme non annulable, vous devez changer l'instruction de retour onCreatweDialog comme ceci:

    /** convert builder to dialog */
    AlertDialog alert = alertDialogBuilder.create();
    /** disable cancel outside touch */
    alert.setCanceledOnTouchOutside(false);
    /** disable cancel on press back button */
    setCancelable(false);

    return alert;
3
ceph3us