Plan du site  
pixel
pixel

Articles - Étudiants SUPINFO

Xamarin Forms – Listview

Par Adeline BASTIDE Publié le 12/02/2017 à 13:51:58 Noter cet article:
(0 votes)
Avis favorable du comité de lecture

Introduction

Xamarin est un outil de développement dans le langage C# .NET, il permet de concevoir des applications cross-plateforme(iOS, Android, Windows Phone).

L’un des principaux avantages de cet outil est le partage d’une partie du code à travers les différentes plateformes. Evitant ainsi une maintenance lourde et fastidieuse.

Il est possible de développer soit sous Xamarin Studio, ou sous Visual Studio en installant l’extension Xamarin.

Xamarin.Forms est une boîte à outils cross-plateforme qui va permettre d’augmenter le code commun. En effet, cela va permettre de définir une interface graphique commune à travers les différentes plateformes, en gardant l’aspect natif des composants de chacun.

Dans cet article, nous allons concevoir une application Xamarin Forms qui utilisera le composant ListView sous l’environnement de Visual Studio.

Création d’une application Xamarin Forms

Pour créer un nouveau projet, il suffit de cliquer sur Fichier -> Nouveau -> Projet…

Dans la boite de dialogue, dans le menu de gauche, Modèles -> Visual C# -> Cross-Platform, il est proposé différents types d’applications, ici nous choisirons Blank App (Xamarin.Forms Portable).

Figure 1. Crée un nouveau projet

Crée un nouveau projet

Xamarin Forms Portable, ou encore Portable Class Library, va créer une solution avec un projet pour chaque plateforme, et un projet commun.

Xamarin Forms Shared, ou encore Shared Project. Elle est utilisée lorsqu’il est nécessaire de partager du code tout en affectant des spécifiés à une ou plusieurs plateformes.

Une fois le projet crée, vous retrouvez dans l’Explorateur de Solution, la structure de votre solution.

Figure 2. Structure projet

Structure projet

Intégration du composant ListView

Il est possible d’utiliser la listview de différentes manières, soit intégrer totalement du côté C#, soit en partageant le code C# avec la vue XAML.

  • Le DataTemplate est définie dans la vue XAML

    Dans le projet Portable, nous allons d’abord crée un nouveau fichier qui va contenir notre classe Character. Pour cela il suffit de faire un clic droit sur le projet, Ajouter -> Nouvel élément… Dans le menu de gauche, la sélection doit être placé sur Cross-Platform, et sélectionné Forms Page.

    Cette classe contiendra seulement deux attributs ainsi qu’un jeu de donnée.

    			class Character
    			{
    				public string LastName { get; set; }
    				public string FirstName { get; set; }
    
    				public static List<Character> getList()
    				{
    					List<Character> l = new List<Character>();
    
    					l.Add(new Character { LastName = "Simpson", FirstName = "Homer" });
    					l.Add(new Character { LastName = "Simpson", FirstName = "Marge" });
    					l.Add(new Character { LastName = "Simpson", FirstName = "Lisa" });
    					l.Add(new Character { LastName = "Simpson", FirstName = "Bart" });
    					l.Add(new Character { LastName = "Simpson", FirstName = "Maggie" });
    					l.Add(new Character { LastName = "Montgomery", FirstName = "Charles" });
    					l.Add(new Character { LastName = "Flanders", FirstName = "Ned" });
    					l.Add(new Character { LastName = "Van Houten", FirstName = "Milhouse" });
    					l.Add(new Character { LastName = "Szyslak", FirstName = "Moe" });
    
    					return l;
    				}
    			}
    			

    Il faut ensuite crée un autre fichier MainPage.cs qui contiendra la listview. Il faut pour ce fichier sélectionner Forms Xaml Page.

    Dans la page MainPage.xaml.cs :

    			public partial class MainPage : ContentPage
    			{
    				public MainPage()
    				{
    					InitializeComponent();
    					myListView.ItemsSource = Character.getList();
    				}
    			}
    			

    Dans la page MainPage.xaml :

    			<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Xamarin_ListView.MainPage">
    				<ContentPage.Content>
    					<StackLayout>
    					<Label Text="Personnages Les Simpsons"></Label>
    					<ListView x:Name="myListView">
    						<ListView.ItemTemplate>
    							<DataTemplate>
    									<ViewCell>
    									<ViewCell.View>
    									  <StackLayout Orientation="Horizontal" Padding="0,20,0,0">                                                  
    										  <Label Text="{Binding FirstName}"></Label>
    										  <Label Text="{Binding LastName}"></Label>
    									</StackLayout>
    									</ViewCell.View>
    									</ViewCell>
    							</DataTemplate>
    						</ListView.ItemTemplate>
    					</ListView>
    					</StackLayout>
    				</ContentPage.Content>
    			</ContentPage>
    			

    Il ne faut pas oublier de définir la page de lancement dans le fichier App.cs.

    			public App()
    			{                     
    				MainPage = new MainPage();
    			}
    			
  • Le DataTemplate est définie dans le code C#

    Pour cette page, il n’est pas nécessaire d’utiliser Forms Xaml Page mais un simple Forms Page est suffisant puisque la partie XAML n’est pas utilisée.

    				public class MainPage : ContentPage
    				{
    					public MainPage()
    					{
    						var mtitle = new Label
    						{
    							Text = "Personnages Les Simpsons",
    							FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
    							HorizontalOptions = LayoutOptions.Start
    						};
    
    						ListView listView = new ListView
    						{
    							ItemsSource = Character.getList(),
    							ItemTemplate = new DataTemplate(() =>
    							{
    								Label lFirstname = new Label();
    								lFirstname.SetBinding(Label.TextProperty, "FirstName");
    
    								Label lLastname = new Label();
    								lLastname.SetBinding(Label.TextProperty, "LastName");
    
    								return new ViewCell
    								{
    									View = new StackLayout
    									{
    										Padding = new Thickness(5, 5),
    										Orientation = StackOrientation.Horizontal,
    										Children =
    										{
    											new StackLayout {
    												Orientation = StackOrientation.Horizontal,
    												Children =
    												{
    													lFirstname,
    													lLastname
    												}
    											}
    										}
    									}
    								};
    							})
    						};
    
    						this.Content = new StackLayout
    						{
    							Children =
    							{
    								mtitle,
    								listView
    							}
    						};
    
    					}
    				}
    				

A ce stade, l’application fonctionne et est prêt à être compilé.

Figure 3. Premier rendu

Premier rendu

Jusque-là, la listview était relativement simple, avec 2 attributs et un affichage texte. Nous allons complexisé un peu la listview en affichant une image.

Pour cela, il faut adapter la classe Character.cs avec cette nouvelle caractéristique.

		class Character
		{
			public string LastName { get; set; }
			public string FirstName { get; set; }

			public string Image { get; set; }

			public static List<Character> getList()
			{
				List<Character> l = new List<Character>();

				l.Add(new Character { LastName = "Simpson", FirstName = "Homer", Image = "homer.png" });
				l.Add(new Character { LastName = "Simpson", FirstName = "Marge", Image = "marge.jpg" });
				l.Add(new Character { LastName = "Simpson", FirstName = "Lisa", Image = "lisa.png" });
				l.Add(new Character { LastName = "Simpson", FirstName = "Bart", Image = "bart.png" });
				l.Add(new Character { LastName = "Simpson", FirstName = "Maggie", Image = "maggie.jpg" });
				l.Add(new Character { LastName = "Montgomery", FirstName = "Charles", Image = "charles.jpg" });
				l.Add(new Character { LastName = "Flanders", FirstName = "Ned", Image = "ned.jpg" });
				l.Add(new Character { LastName = "Van Houten", FirstName = "Milhouse", Image = "milhouse.png" });
				l.Add(new Character { LastName = "Szyslak", FirstName = "Moe", Image = "moe.jpg" });

				return l;
			}
		}
		
  • Dans la vue XAML

    Ajoutez dans la listview une balise <Image>.

    				<StackLayout Orientation="Horizontal" Padding="0,20,0,0">  
                                  <Image Source="{Binding Image}"/>
                                  <Label Text="{Binding FirstName}"></Label>
                                  <Label Text="{Binding LastName}"></Label>
    				</StackLayout>
    				
  • Dans le code C#

    Dans la page MainPage.cs, il faut modifier la listview en ajoutant le composant Image.

    				  ListView listView = new ListView
    					{
    						ItemsSource = Character.getList(),
    						ItemTemplate = new DataTemplate(() =>
    						{                  
    
    							Label lFirstname = new Label();
    							lFirstname.SetBinding(Label.TextProperty, "FirstName");
    
    							Label lLastname = new Label();
    							lLastname.SetBinding(Label.TextProperty, "LastName");
    
    							Image mImage = new Image();
    							mImage.SetBinding(Image.SourceProperty, "Image");
    
    							return new ViewCell
    							{
    								View = new StackLayout
    								{
    									Padding = new Thickness(5, 5),
    									Orientation = StackOrientation.Horizontal,
    									Children =
    									{
    										new StackLayout {
    											Orientation = StackOrientation.Horizontal,
    											Children =
    											{
    												mImage,
    												lFirstname,
    												lLastname
    											}
    										}
    									}
    								}
    							};
    						})
    					};
    				

Il faut bien entendu ne pas oublier d’ajouter les images dans le projet. Pour ce type de projet, c’est-à-dire PCL, il faut rajouter les images au sein de chaque plateforme.

Figure 4. Structure des plateformes

Structure des plateformes

Pour la plateforme Android, les fichiers sont à rajouter dans le dossier Resources -> drawable.

Pour la plateforme iOS, les fichiers sont à rajouter dans le dossier Resources.

Remarque : Pour ajouter des fichiers proprement au sein d'un projet, il suffit de faire clic droit sur le dossier souhaité, Ajouter -> Elément existant…

L’application peut être maintenant être compilé.

Figure 5. Listview avec image

Listview avec image

Les fonctionnalités avancées

  • Context Actions

    Une autre interaction possible sur la listview est le Context Actions. Elle est utile pour effectuer des a actions directement sur la listview. Le Context Actions est interpréter de différentes façons en fonction de la plateforme, pour iOS et Windows Phone est se traduit par un swipe (c’est-à-dire un glissement) sur l’item, mais sur Android, elle se traduit par un presse long sur l’item.

    Cette interaction est créée en utilisant MenuItems. Elle peut être implémentée soit en C# ou en XAML.

    • Dans la vue XAML

      							<ListView x:Name="myListView" RowHeight="60">
      								<ListView.ItemTemplate>
      									<DataTemplate>
      										<ViewCell>
      											<ViewCell.ContextActions>
      											  <MenuItem Clicked="OnMore" CommandParameter="{Binding .}" Text="More" />
      											  <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Delete" IsDestructive="True" />
      											</ViewCell.ContextActions>
      											<ViewCell.View>
      											  <StackLayout Orientation="Horizontal" Padding="0,20,0,0">  
      												<Image Source="{Binding Image}"/>>
      												<Label Text="{Binding FirstName}"></Label>
      												<Label Text="{Binding LastName}"></Label>
      											  </StackLayout>
      											</ViewCell.View>
      										</ViewCell>
      									</DataTemplate>
      								</ListView.ItemTemplate>
      							</ListView>
      						

      Coté code, dans la page MainPage.xaml.cs, on implémente les méthodes associés aux MenuItems.

      						  public void OnMore(object sender, EventArgs e)
      							{
      								var mi = ((MenuItem)sender);
      								DisplayAlert("More", mi.CommandParameter + " more context action", "OK");
      							}
      
      							public void OnDelete(object sender, EventArgs e)
      							{
      								var mi = ((MenuItem)sender);
      								DisplayAlert("Delete", mi.CommandParameter + " delete context action", "OK");
      							}
      						
    • Dans le code C#

      Coté code, il faut donc modifier le code dans la listview, dans le fichier MainPage.cs.

      						ListView listView = new ListView
      						{
      							ItemsSource = Character.getList(),
      							ItemTemplate = new DataTemplate(() =>
      							{
      								
      
      								Label lFirstname = new Label();
      								lFirstname.SetBinding(Label.TextProperty, "FirstName");
      
      								Label lLastname = new Label();
      								lLastname.SetBinding(Label.TextProperty, "LastName");
      
      								Image mImage = new Image();
      								mImage.SetBinding(Image.SourceProperty, "Image");
      
      								var moreAction = new MenuItem { Text = "More", };
      								moreAction.Clicked += (sender, e) =>
      								{
      									MenuItem mi = ((MenuItem)sender);
      									string id = mi.CommandParameter as string;
      									string it = mi.Text as string;
      
      									MessagingCenter.Send(it, "More Information");
      								};
      
      								// Déclarer des items ContextActions
      								var deleteAction = new MenuItem { Text = "Delete", };
      								deleteAction.Clicked += (sender, e) =>
      								{
      									MenuItem mi = ((MenuItem)sender);
      									string id = mi.CommandParameter as string;
      									string it = mi.Text as string;
      
      									MessagingCenter.Send(it, "DeleteThis");
      								};
      
      								ViewCell mViewCell = new ViewCell();
      
      								// Ajouter les items dans ContextActions
      								mViewCell.ContextActions.Add(moreAction);
      								mViewCell.ContextActions.Add(deleteAction);
      
      								View view = new StackLayout
      								{
      									Padding = new Thickness(5, 5),
      									Orientation = StackOrientation.Horizontal,
      									Children =
      										{
      											new StackLayout {
      												Orientation = StackOrientation.Horizontal,
      												Children =
      												{
      													mImage,
      													lFirstname,
      													lLastname,
      
      												}
      											}
      										}
      								};
      
      								mViewCell.View = view;
      								return mViewCell;                        
      							})
      						};
      						

    L’application peut être maintenant être compilé, et tester la nouvelle interaction intégrée.

    Figure 6. Listview avec ContextAction

    Listview avec ContextAction

  • Selection

    • Dans la vue XAML

      Il faut tout d’abord modifier la page MainPage.xaml, dans la listview.

      						<ListView x:Name="myListView" RowHeight="60" ItemSelected="OnSelect">
      							<ListView.ItemTemplate>
      								<DataTemplate>
      								  <ViewCell>
      									<ViewCell.ContextActions>
      									  <MenuItem Clicked="OnMore" CommandParameter="{Binding .}" Text="More" />
      									  <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Delete" IsDestructive="True" />
      									</ViewCell.ContextActions>
      									<ViewCell.View>
      									  <StackLayout Orientation="Horizontal" Padding="0,20,0,0">   
      										<Image Source="{Binding Image}"/>
      										<Label Text="{Binding FirstName}"></Label>
      										<Label Text="{Binding LastName}"></Label>
      									  </StackLayout>
      									</ViewCell.View>
      								  </ViewCell>
      								</DataTemplate>
      							</ListView.ItemTemplate>
      						</ListView>
      						

      Puis coté code, dans la page MainPage.xaml.cs, la méthode OnSelect(), avec l’action que souhaité :

      						  void OnSelect(object sender, SelectedItemChangedEventArgs e)
      							{
      								if (e.SelectedItem == null)
      								{
      									return;
      								}
      								DisplayAlert("Item Selected", e.SelectedItem.ToString(), "Ok");
      								ListView lst = (ListView)sender;
      								lst.SelectedItem = null;
      							}
      						
    • Dans la vue XAML

      Dans le fichier MainPage.cs, il faut spécifier l’action de sélection dans la listview, et implémenter la méthode.

      						public MainPage()
      						  {  
      							…
      							ListView listView = new ListView
      									{…}
      								…
      							   listView.ItemSelected += OnSelect;
      						   }  
      						void OnSelect(object sender, SelectedItemChangedEventArgs e)
      								{
      									if (e.SelectedItem == null)
      									{
      										return; 
      									}
      									DisplayAlert("Item Selected", e.SelectedItem.ToString(), "Ok");       
      									ListView lst = (ListView)sender;
      									lst.SelectedItem = null;
      								}
      						

      Remarque : Si la sélection souhaite être gardé, il faut commenter les dernières lignes de la méthode.

      Figure 7. Listview avec SelectedItem

      Listview avec SelectedItem

D'autres interactions sont possible, , tel que le Pull-to-Refresh. Consistant à un glissement vers le bas de la liste.

Remarque : à partir de Xamarin.Forms 1.4.3, Pull-to-Refresh n'est pas pris en charge sur Windows Phone 8.1.

Conclusion

Comme montré à travers ce mini-projet, la conception d'une application montre des avantages non négligeable. Ici, tout le code à été écrit qu'une seule fois pour plusieurs plateformes.

Nous avons vu la listview au sein de Xamarin, et plus précisément Xamarin Forms. Il y a bien sûr d'autres possibilités d'exploiter ce composant, pour plus d'informations, ici la documentation officielle de Xamarin.

A propos de SUPINFO | Contacts & adresses | Enseigner à SUPINFO | Presse | Conditions d'utilisation & Copyright | Respect de la vie privée | Investir
Logo de la société Cisco, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société IBM, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sun-Oracle, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Apple, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sybase, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Novell, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Intel, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Accenture, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société SAP, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Prometric, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Toeic, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo du IT Academy Program par Microsoft, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management

SUPINFO International University
Ecole d'Informatique - IT School
École Supérieure d'Informatique de Paris, leader en France
La Grande Ecole de l'informatique, du numérique et du management
Fondée en 1965, reconnue par l'État. Titre Bac+5 certifié au niveau I.
SUPINFO International University is globally operated by EDUCINVEST Belgium - Avenue Louise, 534 - 1050 Brussels