Boîtes de dialogues

Fenêtres interactives dans Android

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

L'utilisation des dialogs a été popularisée dans le monde de l'internet grâce à la démocratisation du jQuery. Android a également intégré cette fonctionnalité basée sur les fenêtres capables d'interagir avec l'utilisateur. Il est même allé plus loin et a groupé ces dialogs en fonction de leur destination. Dans notre application on employera les dialogs pour : marquer le chargement d'un élément, afficher une erreur ou une question de confirmation.

Dialog sous Android

Dialog est donc une fenêtre qui ne prend jamais toute la largeur de l'écran et qui permet à l'utilisateur d'effectuer une action (prendre une décision, renseigner des informations supplémentaires). Chaque dialog est composé de 3 parties :
- titre : permet de donner un titre à l'action que l'utilisateur est invitée à effectuer
- contenu : affiche ce que l'utilisateur peut faire. Le contenu peut contenir aussi bien un simple message textuel qu'un layout plus complexe comme un formulaire.
- actions : pas plus que 3 boutons qui permettent soit de valider la décision de l'utilisateur, soit de l'annuler. Une des 3 décisions peut être prise : positive, négative, neutre. La dernière doit être utilisée uniquement quand l'utilisateur ne veut pas effectuer aucune des deux premières (ne veut ni annuler, ni accepter).

Android regroupe 2 types de boîtes de dialogue : AlertDialog et DialogFragment. Les deux peuvent implémenter d'autres types de dialogues. Dans le cas de ce premier, il s'agit de : DatePickerDialog, TimePickerDialog, ProgressDialog. Les deux premiers permettent de choisir la date ou l'heure. Le dernier est utilisé pour indiquer la progression dans le traitement d'une tâche. En ce qui concerne AlertDialog en lui-même, il est un élément qui permet d'afficher les 3 boutons mentionnés et, ainsi, d'effectuer une action.

Implémenter AlertDialog sous Android

Après une partie d'introduction, passons maintenant à l'implémentation de l'AlertDialog dans le code. Notre application l'utilise dans plusieurs endroits : il affiche de simples messages avec le choix Oui/Non aussi bien que des formulaires. Ici on présentera le cas plus complexe, celui des formulaires. Le formulaire va nous permettre d'emprunter un livre. Voici le layout utilisé :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:orientation="vertical" >

    <TextView
        android:id="@+id/borrowingDateLabel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/label_borrowing_date" />
    />
    <DatePicker 
        android:id="@+id/borrowingDatePicker"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" /> 
    
    
</LinearLayout>

Le formulaire contient un DatePicker grâce auquel on peut spécifier la date d'emprunt souhaitée. Après le click sur le bouton "emprunter", cette date sera récupérée par la méthode onClick() de l'implémentation du DialogInterface. Dans le cas d'un click sur "annuler", la boîte de dialogue sera fermée :

public class BookHelperView {
    // ...
    public void constructFooter(PlacementTextView placementView) {
        // ...
        final Resources resources = activity.getResources();
        TextView textBorrow = new TextView(activity);
        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final View borrowingView = inflater.inflate(R.layout.borrowing_form, (ViewGroup) null, true);
        final DatePicker datePicker = (DatePicker) borrowingView.findViewById(R.id.borrowingDatePicker);
        //datePicker.setMinDate(UniversalConverter.fromDateTimeToLong(new Date()));
        textBorrow.setText(resources.getString(R.string.action_borrow));
        textBorrow.setTextAppearance(activity, R.style.clickable_text);
        textBorrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(LOG_TAG, "CLicked on view " + view);
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
                alertDialogBuilder.setTitle(resources.getString(R.string.borrow_title));  
                alertDialogBuilder.setView(borrowingView);
                alertDialogBuilder.setCancelable(true)
                .setPositiveButton(resources.getString(R.string.borrow_do), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) { 
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.YEAR, datePicker.getYear());
                        calendar.set(Calendar.MONTH, datePicker.getMonth());
                        calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());

                        Map params = new HashMap();
                        params.put("activity", activity);
                        params.put("id", book.getId());
                        params.put("date", calendar.getTime());
                        BorrowingMakerAsynTask borrowingMakerAsynTask = new BorrowingMakerAsynTask();
                        borrowingMakerAsynTask.execute(params);
                        Log.d(LOG_TAG, "Choosed date " + datePicker.getDayOfMonth() + "-" + datePicker.getMonth() + "-"+ datePicker.getYear());
                    }
                })
                .setNegativeButton(resources.getString(R.string.cancel),new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,int id) {
                        dialog.cancel();
                    }
                });
                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();
                // show it
                alertDialog.show();
            }
        });
        // ...
    }
}

Comment fonctionne l'affichage de l'AlertDialog sous Android ? Tout d'abord on crée un élément qui va déclencher la création de notre dialog. Il s'agit du TextView textBorrow = new TextView(activity) à qui on associe un écouteur via textBorrow.setOnClickListener(new View.OnClickListener(){}. L'écouteur en question invoque le constructeur de la boîte de dialogue par AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity). Plus loin on fait tout le paramétrage en indiquant le titre et la vue à utiliser. En indiquant alertDialogBuilder.setCancelable(true) on permet à l'utilisateur d'annuler le dialogue grâce à la touche "Retour".

Les deux méthodes, setPositiveButton() et setNegativeButton(), spécifient le comportement que le dialog doit prendre suite à la décision positive et negative de l'utilisateur par rapport à l'action demandée. En occurrence, pour l'action positive, on récupère la date de l'emprunt souhaitée et ensuite on la passe en paramètre à la tâche asynchrone BorrowingMakerAsynTask.

En ce qui concerne la décision négative, on appelle la méthode cancel() qui cachera le dialog.

Implémenter ProgressDialog sous Android

ProgressDialog est une sous-classe de l'AlertDialog. Il permet d'indiquer à l'utilisateur qu'une action est en cours d'être traitée (chargement, sauvegarde d'un grand fichier etc.). Dans notre application on l'utilisera pour alerter l'utilisateur du traitement des informations de connexion sur l'écran "Mon compte". On n'utilisera pas de layout mais juste un simple message textuel. Le dialog sera automatiquement caché dans la méthode qui gère la réponse de web service, via progressDialog.dismiss();. A part cela, au chargement, on désactive le bouton qui permet de soumettre les données de connexion (submitPreferencies.setEnabled(false);).Il sera réactivé dans les deux cas : quand on traitera la réponse du web service ou quand l'utilisateur décidera d'annuler le chargement. Voici le code qui illustre ces fonctionnalités :

afficher le code

TODO : présenter DialogFragment et différence avec AlertDialog

Bartosz KONIECZNY Fenêtres UI

Une question ? Une remarque ?

*

*

Un conseil MySQL

Comment importer un fichier SQL depuis la console ?

L'importation des fichiers .sql se déroule avec la commande suivante :

mysql -u root --password=root -h 127.0.0.1 -D myDatabase < tab_to_import.sql