Tutoriel “Développer nativement pour iOS et Android en C# & .Net avec Xamarin” (partie 2)

Tutoriel : Développer nativement pour iOS et Android en C#/.Net avec Xamarin (partie 2)

Introduction

Voici le deuxième tutoriel de la série dans lequel nous mettrons en place la couche spécifique à Android de notre application Shake8. Voici les prérequis dont vous aurez besoin :

La solution définitive sera la suivante :

AndroidSolution

Le code source est disponible ici.

Création du projet

Dans la solution Shake8, ajoutez un nouveau projet de type “Android Application”. Nommez le projet Shake8.Droid.

projetAndroid

Le projet a créé automatiquement une référence à Mono.Android :

referenceAMonoAndroid

Le projet s’appuie sur la couche commune Shake8.CrossPlatform. Créez les mêmes dossiers que le projet Shake8.CrossPlatform en créant des liens (“link”) vers les fichiers correspondants. L’icône “lien” apparaît sur chacun des fichiers :

lien

Remarques :

  • On aurait aussi pu créer une référence à Shake8.CrossPlatform, mais de cette façon nous avons accès à tout le code si on décide d’ouvrir seulement le projet Shake8.Droid;
  • Nous n’avons pas nommé le projet Shake8.Android pour ne pas qu’il puisse avoir de confusion dans le code avec la librairie Mono.Android.

Dans les options du projet, il est possible de choisir le framework cible d’Android. Pour notre test, nous disposons d’un téléphone sous Android 2.3 :

androidOption

 La couche Application et UI

andoidApplication

La couche application du projet Shake8.Droid contient les classes spécifiques à la plateforme Android nécessaires pour “binder” les objets à exposer dans l’UI. Dans notre application, nous souhaitons présenter la liste des “balls” et des choix. Pour cela, nous allons utiliser une ListView. Android.Resource.Layout offre la possibilité de présenter une liste d’objets de 4 façons différentes :

  • SimpleListItem1 :  une ligne de texte;
  • SimpleListItem2 : deux lignes de texte;
  • TwoLineListItem  : deux lignes de texte;
  • ActivityListItem : une ligne de texte avec une image.

Chaque ligne de la liste a un style par défaut associé, comme le montrent les vues correspondantes suivantes :

 

Une ListView nécessite un Adaptater pour spécifier comment doit être affiché un objet. Android propose des Adaptater mais il est possible d’en customiser. C’est ce que nous allons faire dans notre projet. L’écran d’accueil de l’application affiche la liste des “balls”. Lorsque l’utilisateur a entré des choix, nous souhaitons afficher “Shake me to make your choice!”. Lorsque l’utilisateur n’a pas entré de choix, nous souhaitons afficher “Please enter some choices”. Voici un exemple du résultat attendu :

ball

Lorsqu’on clique sur une ball (par exemple “laquelle ce soir?”), nous souhaitons afficher la liste des choix avec une “check box”. Celle-ci sera cochée si un choix a été fait :

choix       choixFait

(Je parle de bière dans l’exemple bien sûr 😎 )

Lorsqu’on édite une “ball”, on affiche les choix plus simplement :

simpleList

 Les classes nécessaires pour montrer à l’écran une ListView sont les suivantes :

Voici la description de chaque classe :

  • ListView : UI permettant d’afficher une vue scrollable contenant une liste de lignes;
  • Activity : concept purement spécifique à Android. Alors qu’habituellement une méthode static “Main” permet de démarrer une application, dans Android, n’importe quelle application peut être lancée via n’importe quelle Activity d’une application. En pratique, la plupart des applications ont une Activity spécifique comme point d’entrée. Si une application crashe ou se termine, l’OS est capable de relancer l’application à la dernière Activity ouverte ou n’importe laquelle qui se trouve dans la pile. En outre, l’OS peut aussi mettre une Activity en pause;
  • BaseAdapter : classe de base qui permet de binder une source de données à une ListView;
  • ArrayAdapter : Adaptater qui permet de binder un Array d’objets;
  • CursorAdapter : CursorAdapter ou SimpleCursorAdapter permet d’afficher des données basées sur une requête SQLite.

Nous allons créer dans la couche Application 3 adaptaters :

  • BallListAdaptater;
  • ChoiceListAdaptater;
  • ChoiceListSimpleAdaptater.

Mais avant, créons d’abord notre première vue.

Fichier BallListItem.axml

Dans le dossier Resources/Layout créer un fichier BallListItem.axml. Ce fichier représente la vue d’une ligne de notre liste de “Ball”.

BallListItem

Un fichier .axml sur Android est l’équivalent d’un ficher .xaml. Il permet de “dessiner” l’interface. Xamarin Studio propose une boîte à outil équivalent à celle de Visual Studio :

boiteAoutil

Dans notre fichier, nous créons deux TextView, une pour afficher le nom d’une “ball”, l’autre pour afficher le message que l’on souhaite :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/lstItemBall"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/txtName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/txtTheChoice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
LinearLayout>

 

Ficher BallListAdaptater.cs

Notez que pour donner un identifiant à chaque élément, il est nécessaire de faire précéder la valeur souhaitée par “@+id/”. Créons maintenant l’Adaptater correspondant. Nous créons une class BallListAdaptater qui hérite de BaseAdaptater :

using System;
using System.Collections.Generic;
using Android.Widget;
using Shake8.CrossPlatform.Entity;
using Android.App;
using Android;

namespace Shake8.Droid.Application {
    public class BallListAdapter : BaseAdapter {
        protected Activity context = null;
        protected IList balls = new List();

        public BallListAdapter (Activity context, IList balls) : base ()
        {
            this.context = context;
            this.balls = balls;
        }

        public override Ball this[int position]
        {
            get { return balls[position]; }
        }

        public override long GetItemId (int position)
        {
            return position;
        }

        public override int Count
        {
            get { return balls.Count; }
        }

        public override Android.Views.View GetView (int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
        {
            // Get our object for position
            var item = balls[position];

            var view = (convertView ??
                context.LayoutInflater.Inflate(
                    Resource.Layout.BallListItem,
                    parent,
                    false))   as LinearLayout;
            view.VerticalScrollBarEnabled = true;
            view.ScrollBarStyle = Android.Views.ScrollbarStyles.OutsideInset;

            // Find references to each subview in the list item's view
            var txtName = view.FindViewById(Resource.Id.txtName);
            var txtDescription = view.FindViewById(Resource.Id.txtTheChoice);

            //Assign item's values to the various subviews
            txtName.SetText (item.Name, TextView.BufferType.Normal);
            txtName.SetTextSize (Android.Util.ComplexUnitType.Px, 35);

            var itemChoices = Shake8.CrossPlatform.Business.BallManager.GetChoicesByBallID (item.ID);
            if (itemChoices.Count == 1) {
                txtDescription.SetText ("Add at least one more choice so you'll be ready shake", TextView.BufferType.Normal);
            }
            else if (itemChoices.Count > 0) {
                if (item.TheChoiceID > 0) {
                    var choice = Shake8.CrossPlatform.Business.BallManager.GetChoice (item.TheChoiceID);
                    txtDescription.SetText ("Result: "+choice.Name, TextView.BufferType.Normal);
                } else {
                    txtDescription.SetText ("Shake me to make your choice!", TextView.BufferType.Normal);
                }
            }
            else
            {
                txtDescription.SetText ("Please enter some choices", TextView.BufferType.Normal);
            }

            //Finally return the view
            return view;
        }
    }
}

 

Nous redéfinissons la méthode GetView afin de définir le comportement de l’affichage dans les TextViews précédemment cités. On procède de la même façon pour les vues des choix. Nous avons terminé le développement pour Android. Prochainement, vous trouverez les tutoriels pour iOS et Windows Phone.

Conclusion

Nous avons réalisé l’architecture suivante :

image

Le code source est disponible ici.

La prochaine étape sera de développer la partie spécifique à iOS. (Je pars en voyage loin loin je vous donne rdv en avril 2015 sur mon futur blog perso pour la suite du tutoriel)

Share
Cécile BOUNSINH
Cécile BOUNSINH

6383

Leave a Reply

Your email address will not be published. Required fields are marked *