Licence CC BY-SA

DialogFragment

Les boites de dialogue sont présentes depuis les toutes premières versions d'Android. Avec la version 3.0, les DialogFragment amènent les fragments dans ce composant. Ils permettent d'afficher une boite de dialogue à l'utilisateur de manière beaucoup plus souple et plus complète que l'API utilisée dans les versions antérieures.

Créer un DialogFragment

Les API AlertDialog et Dialog sont des concepts régulièrement utilisés depuis toujours dans le développement d'applications Android. L'idée derrière cette mise à niveau est de ré-utiliser ce type de composant mais en lui attachant des fragments. C'est une pratique qui permettra de concevoir des boites de dialogue infiniment plus puissantes et réutilisables que les anciennes.

DialogFragment servira de conteneur pour un fragment simple. Il le transformera en boite de dialogue et fournira le style et la structure de la boite. Cette classe fournit tous les contrôles nécessaires pour créer la boite et gérer son apparence.

Pour spécifier qu'un fragment est destiné à être affiché dans une boite de dialogue, le futur fragment doit étendre la classe DialogFragment et redéfinir certaines méthodes. Ces méthodes sont utiles pour sa gestion et pour son intégration dans la boite. Sans surprise, deux méthodes sont définies et redéfinies :

  • public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) : Pour désérialiser le fichier XML représentant le fragment voulu et pour donner un titre à la boite de dialogue (ce dernier étant optionnel).
  • public static MyDialogFragment newInstance() : Pour encapsuler la création du fragment et en connaitre les données potentielles.

La classe suivante donne un exemple d'implémentation :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.siteduzero.android.dialog;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

import com.siteduzero.android.R;

public class MyDialogFragment extends DialogFragment {
    public static MyDialogFragment newInstance(int title) {
        MyDialogFragment dialog = new MyDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        dialog.setArguments(args);
        return dialog;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_dialog, container, false);

        Button button = (Button) v.findViewById(R.id.buttonShow);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                ((DialogActivity) getActivity())
                        .showDialogType(DialogActivity.TYPE_ALERT_DIALOG);
            }
        });

        getDialog().setTitle(getArguments().getInt("title"));

        return v;
    }
}

Pour afficher la boite de dialogue, il suffit d'appeler la méthode public int show (FragmentTransaction transaction, String tag) sur une instance d'un DialogFragment comme expliqué dans la documentation officielle.

Résultat de l'exécution des boîtes de dialogue DialogFragment

Créer un AlertDialog

Le fonctionnement d'une AlertDialog reste inchangé dans les grandes lignes et les nouveautés ressemblent au fonctionnement des DialogFragment. Il est toujours nécessaire d'étendre la classe DialogFragment mais il faut redéfinir une nouvelle méthode, public Dialog onCreateDialog(Bundle savedInstanceState). C'est dans cette méthode qui va falloir utiliser le builder, AlertDialog.Builder.

Vous êtes censé savoir comment créer un AlertDialog. Je ne rentrerai donc pas dans les détails en ce qui concerne sa création mais beaucoup plus en ce qui concerne son intégration dans un fragment. En fait, c'est vraiment très semblable au DialogFragment et vous devez avoir une petite idée de la manière de s'y prendre avec les connaissances que je viens de vous apporter et ainsi que celles portant sur sa création dans une Activity.

Bien entendu, ce n'est pas exactement la même chose. Nous n'allons pas devoir redéfinir la méthode public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) mais public Dialog onCreateDialog(Bundle savedInstanceState). A partir de là, il nous suffit de retourner une AlertDialog avec l'aide d'un builder.

La redéfinition de la méthode donnera quelque chose comme :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int title = getArguments().getInt("title");

    return new AlertDialog.Builder(getActivity())
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle(title)
            .setNegativeButton(R.string.alert_dialog_cancel,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                int whichButton) {
                            ((DialogActivity) getActivity())
                                    .doNegativeClick();
                        }
                    })
            .setPositiveButton(R.string.alert_dialog_ok,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                int whichButton) {
                            ((DialogActivity) getActivity())
                                    .doPositiveClick();
                        }
                    }).create();
}

N'oubliez pas d'implémenter la méthode static pour créer une instance comme nous l'avons fait avec DialogFragment.

Ainsi, le résultat est le suivant :

Résultat de l'exécution des boîtes de dialogue AlertDialog

Afficher une boite de dialogue

Dernière petite chose avant de terminer ce chapitre. Nous allons rapidement voir comment intégrer nos boites de dialogue dans une activité. Vous comprendrez que ce n'est vraiment pas compliqué puisqu'il s'agit d'un fragment comme un autre. C'est la raison pour laquelle je vais vous laisser réfléchir à la question. Si vous avez bien compris la matière que je vous ai enseigné dans les chapitres précédents, cela ne devrait pas vous prendre trop longtemps.

Sachez simplement que vous devez implémenter un certain nombre de méthode :

  • public void doNegativeClick() : Appelée lorsqu'on clique sur le bouton négatif de l'AlertDialog.
  • public void doPositiveClick() : Appelée lorsqu'on clique sur le bouton positif de l'AlertDialog.
  • public void showAlertDialog(View v) : Appelée au clique de l'utilisateur sur le bouton de notre activité destiné à l'affichage de l'AlertDialog.
  • public void showDialogFragment(View v) : Appelée au clique de l'utilisateur sur le bouton de notre activité destinée à l'affichage de DialogFragment.
  • protected void showDialogType(int type) : Pour basculer dynamiquement entre les différentes boîtes de dialogue.

Je vous laisse à vos lignes de codes. Vous trouverez ma solution et son résultat à la suite de ce chapitre.

Correction

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.siteduzero.android.dialog;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;

import com.siteduzero.android.R;
import com.siteduzero.android.dialog.alert.MyAlertDialog;

public class DialogActivity extends FragmentActivity {
    public static final int TYPE_DIALOG_FRAGMENT = 1;
    public static final int TYPE_ALERT_DIALOG = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
    }

    protected void showDialogType(int type) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
        if (prev != null) {
            ft.remove(prev);
        }
        ft.addToBackStack(null);

        DialogFragment newFragment = null;
        switch (type) {
        case TYPE_DIALOG_FRAGMENT:
            newFragment = MyDialogFragment
                    .newInstance(R.string.title_fragment_dialog);
            break;
        case TYPE_ALERT_DIALOG:
            newFragment = MyAlertDialog
                    .newInstance(R.string.title_fragment_dialog_alert);
            break;
        }
        newFragment.show(ft, "dialog");
    }

    public void showDialogFragment(View v) {
        showDialogType(TYPE_DIALOG_FRAGMENT);
    }

    public void showAlertDialog(View v) {
        showDialogType(TYPE_ALERT_DIALOG);
    }

    public void doPositiveClick() {
        // TODO Do something
    }

    public void doNegativeClick() {
        // TODO Do something
    }
}

Résultat de l'exécution de l'activité pour afficher nos boîtes de dialogue


En résumé

  • DialogFragment est une sous classe de Fragment qui permet de contenir des fragments dans des boites de dialogue.
  • Il existe 2 types de boites de dialogue : DialogFragment qui est générique que vous contrôlez de A à Z ; AlertDialog qui est moins générique car rajoutant des boutons en bas de la boite.
  • Ces boites de dialogue se lancent à peu de chose près comme un fragment normal.