Partager via


Personnalisation de l’apparence des cellules ListView

La Xamarin.FormsListView classe est utilisée pour présenter des listes défilables, qui peuvent être personnalisées à l’aide d’éléments ViewCell . Un ViewCell élément peut afficher du texte et des images, indiquer un état true/false et recevoir une entrée utilisateur.

Cellules intégrées

Xamarin.Forms est fourni avec des cellules intégrées qui fonctionnent pour de nombreuses applications :

  • TextCell les contrôles sont utilisés pour afficher du texte avec une deuxième ligne facultative pour le texte détaillé.
  • ImageCell les contrôles sont similaires à TextCells, mais incluent une image à gauche du texte.
  • SwitchCell les contrôles sont utilisés pour présenter et capturer des états activés/désactivés ou true/false.
  • EntryCell les contrôles sont utilisés pour présenter des données textuelles que l’utilisateur peut modifier.

Les contrôles et EntryCell les SwitchCell contrôles sont plus couramment utilisés dans le contexte d’un TableView.

TextCell

TextCell est une cellule permettant d’afficher du texte, éventuellement avec une deuxième ligne sous forme de texte détaillé. La capture d’écran suivante montre TextCell les éléments sur iOS et Android :

Exemple TextCell par défaut

TextCells est rendu en tant que contrôles natifs au moment de l’exécution. Les performances sont donc très bonnes par rapport à une commande personnalisée ViewCell. TextCells est personnalisable, ce qui vous permet de définir les propriétés suivantes :

  • Text : texte affiché sur la première ligne, en police volumineuse.
  • Detail : texte affiché sous la première ligne, dans une police plus petite.
  • TextColor : couleur du texte.
  • DetailColor : couleur du texte de détail

La capture d’écran suivante montre TextCell les éléments avec des propriétés de couleur personnalisées :

Exemple TextCell personnalisé

ImageCell

ImageCell, par exemple TextCell, peut être utilisé pour afficher du texte et du texte de détail secondaire, et offre de bonnes performances à l’aide des contrôles natifs de chaque plateforme. ImageCell diffère de TextCell celui-ci pour afficher une image à gauche du texte.

La capture d’écran suivante montre ImageCell les éléments sur iOS et Android : « Exemple ImageCell par défaut »

ImageCell est utile lorsque vous devez afficher une liste de données avec un aspect visuel, par exemple une liste de contacts ou de films. ImageCellsont personnalisables, ce qui vous permet de définir :

  • Text : texte affiché sur la première ligne, en police volumineuse
  • Detail : texte affiché sous la première ligne, dans une police plus petite
  • TextColor : couleur du texte
  • DetailColor : couleur du texte de détail
  • ImageSource : image à afficher en regard du texte

La capture d’écran suivante montre ImageCell les éléments avec des propriétés de couleur personnalisées : « Exemple ImageCell personnalisé »

Cellules personnalisées

Les cellules personnalisées vous permettent de créer des dispositions de cellules qui ne sont pas prises en charge par les cellules intégrées. Par exemple, vous pouvez présenter une cellule avec deux étiquettes qui ont un poids égal. Un TextCell serait insuffisant parce que l’étiquette TextCell a une étiquette qui est plus petite. La plupart des personnalisations de cellule ajoutent des données en lecture seule supplémentaires (telles que des étiquettes, des images ou d’autres informations d’affichage).

Toutes les cellules personnalisées doivent dériver de ViewCellla même classe de base que tous les types de cellules intégrés utilisent.

Xamarin.Forms offre un comportement de mise en cache sur le ListView contrôle qui peut améliorer les performances de défilement pour certains types de cellules personnalisées.

La capture d’écran suivante montre un exemple de cellule personnalisée :

« Exemple de cellule personnalisé »

XAML

La cellule personnalisée affichée dans la capture d’écran précédente peut être créée avec le code XAML suivant :

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="demoListView.ImageCellPage">
    <ContentPage.Content>
        <ListView  x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout BackgroundColor="#eee"
                        Orientation="Vertical">
                            <StackLayout Orientation="Horizontal">
                                <Image Source="{Binding image}" />
                                <Label Text="{Binding title}"
                                TextColor="#f35e20" />
                                <Label Text="{Binding subtitle}"
                                HorizontalOptions="EndAndExpand"
                                TextColor="#503026" />
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

Le code XAML fonctionne comme suit :

  • La cellule personnalisée est imbriquée à l’intérieur d’un DataTemplate, qui est à l’intérieur ListView.ItemTemplate. Il s’agit du même processus que l’utilisation de n’importe quelle cellule intégrée.
  • ViewCell est le type de la cellule personnalisée. L’enfant de l’élément DataTemplate doit être de la classe ou en dériver ViewCell .
  • À l’intérieur du , la ViewCelldisposition peut être gérée par n’importe quelle Xamarin.Forms disposition. Dans cet exemple, la disposition est gérée par un StackLayout, ce qui permet de personnaliser la couleur d’arrière-plan.

Remarque

Toute propriété pouvant StackLayout être liée peut être liée à l’intérieur d’une cellule personnalisée. Toutefois, cette fonctionnalité n’est pas affichée dans l’exemple XAML.

Code

Une cellule personnalisée peut également être créée dans le code. Tout d’abord, une classe personnalisée dérivée de ViewCell doit être créée :

public class CustomCell : ViewCell
    {
        public CustomCell()
        {
            //instantiate each of our views
            var image = new Image ();
            StackLayout cellWrapper = new StackLayout ();
            StackLayout horizontalLayout = new StackLayout ();
            Label left = new Label ();
            Label right = new Label ();

            //set bindings
            left.SetBinding (Label.TextProperty, "title");
            right.SetBinding (Label.TextProperty, "subtitle");
            image.SetBinding (Image.SourceProperty, "image");

            //Set properties for desired design
            cellWrapper.BackgroundColor = Color.FromHex ("#eee");
            horizontalLayout.Orientation = StackOrientation.Horizontal;
            right.HorizontalOptions = LayoutOptions.EndAndExpand;
            left.TextColor = Color.FromHex ("#f35e20");
            right.TextColor = Color.FromHex ("503026");

            //add views to the view hierarchy
            horizontalLayout.Children.Add (image);
            horizontalLayout.Children.Add (left);
            horizontalLayout.Children.Add (right);
            cellWrapper.Children.Add (horizontalLayout);
            View = cellWrapper;
        }
    }

Dans le constructeur de page, la propriété de ItemTemplate ListView est définie sur un DataTemplate type spécifié CustomCell :

public partial class ImageCellPage : ContentPage
    {
        public ImageCellPage ()
        {
            InitializeComponent ();
            listView.ItemTemplate = new DataTemplate (typeof(CustomCell));
        }
    }

Modifications du contexte de liaison

Lors de la liaison à des instances d’un BindableProperty type de cellule personnalisé, les contrôles d’interface utilisateur affichant les BindableProperty valeurs doivent utiliser le OnBindingContextChanged remplacement pour définir les données à afficher dans chaque cellule, plutôt que le constructeur de cellule, comme illustré dans l’exemple de code suivant :

public class CustomCell : ViewCell
{
    Label nameLabel, ageLabel, locationLabel;

    public static readonly BindableProperty NameProperty =
        BindableProperty.Create ("Name", typeof(string), typeof(CustomCell), "Name");
    public static readonly BindableProperty AgeProperty =
        BindableProperty.Create ("Age", typeof(int), typeof(CustomCell), 0);
    public static readonly BindableProperty LocationProperty =
        BindableProperty.Create ("Location", typeof(string), typeof(CustomCell), "Location");

    public string Name
    {
        get { return(string)GetValue (NameProperty); }
        set { SetValue (NameProperty, value); }
    }

    public int Age
    {
        get { return(int)GetValue (AgeProperty); }
        set { SetValue (AgeProperty, value); }
    }

    public string Location
    {
        get { return(string)GetValue (LocationProperty); }
        set { SetValue (LocationProperty, value); }
    }
    ...

    protected override void OnBindingContextChanged ()
    {
        base.OnBindingContextChanged ();

        if (BindingContext != null)
        {
            nameLabel.Text = Name;
            ageLabel.Text = Age.ToString ();
            locationLabel.Text = Location;
        }
    }
}

Le OnBindingContextChanged remplacement est appelé lorsque l’événement BindingContextChanged se déclenche, en réponse à la valeur de la BindingContext propriété qui change. Par conséquent, lorsque les BindingContext modifications sont apportées, les contrôles d’interface utilisateur affichant les BindableProperty valeurs doivent définir leurs données. Notez que la BindingContext valeur à case activée doit être case activéenull, car elle peut être définie par Xamarin.Forms le garbage collection, ce qui entraîne à son tour l’appel de OnBindingContextChanged remplacement.

Vous pouvez également lier des contrôles d’interface utilisateur aux BindableProperty instances pour afficher leurs valeurs, ce qui supprime la nécessité de remplacer la OnBindingContextChanged méthode.

Remarque

En cas de OnBindingContextChangedsubstitution, vérifiez que la méthode de la classe de OnBindingContextChanged base est appelée afin que les délégués inscrits reçoivent l’événement BindingContextChanged .

En XAML, la liaison du type de cellule personnalisé aux données peut être obtenue, comme illustré dans l’exemple de code suivant :

<ListView x:Name="listView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:CustomCell Name="{Binding Name}" Age="{Binding Age}" Location="{Binding Location}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Cela lie les Namepropriétés , Ageet Location pouvant être liées dans l’instance CustomCell , aux Namepropriétés , Ageet Location aux propriétés de chaque objet de la collection sous-jacente.

La liaison équivalente en C# est illustrée dans l’exemple de code suivant :

var customCell = new DataTemplate (typeof(CustomCell));
customCell.SetBinding (CustomCell.NameProperty, "Name");
customCell.SetBinding (CustomCell.AgeProperty, "Age");
customCell.SetBinding (CustomCell.LocationProperty, "Location");

var listView = new ListView
{
    ItemsSource = people,
    ItemTemplate = customCell
};

Sur iOS et Android, si les ListView éléments de recyclage et la cellule personnalisée utilisent un renderer personnalisé, le renderer personnalisé doit implémenter correctement la notification de modification de propriété. Lorsque les cellules sont réutilisées, leurs valeurs de propriété changent lorsque le contexte de liaison est mis à jour vers celle d’une cellule disponible, avec PropertyChanged des événements déclenchés. Pour plus d’informations, consultez Personnalisation d’un ViewCell. Pour plus d’informations sur le recyclage des cellules, consultez Stratégie de mise en cache.