• laurent@lioncoding.com

UI: Concevoir un Timeline dans Xamarin.Forms


Il sera question dans cet article de concevoir un Timeline montrant l’historique des activités liées à un compte Twitter d’un utilisateur X comme le montre l’image sur le téléphone ci-dessus.

Un Timeline est une interface utilisateur permettant de tracer l’historique des évènements liés à un compte, à une activité, …

Création du projet Cross-platform Xamarin

N.B: J’utilise Visual Studio 2019 pour cet article. Pour ceux qui utilisent VS2017, le procédé de création d’un projet Xamarin est le même que celui présenté dans mes articles précédents.

Sélectionnez le type de projet Application mobile(Xamarin.Forms) puis sur Suivant

Entrez le nom du projet: Timeline et cliquez sur Créer

Puis sélectionnez le modèle Vide.

Ajout des packages nuget

En observant le Timeline se trouvant en début d’article, l’on constate des images avec des formes rondes. Pour appliquer des transformations de type cercles aux images, nous utiliseront le plugin Xamarin.FFImageLoading.Forms et Xamarin.FFImageLoading.Transformations

Initialisations et Configurations

Le plugin FFImageLoading doit être initialisé dans le projet Android avant utilisation.

Projet Android

  • Initialisation dans le fichier MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(savedInstanceState);
    // Init FFImageLoading plugin
    CachedImageRenderer.Init(false);
    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
    LoadApplication(new App());
}

Pour cet article je ne présenterai pas les codes des Models et Services. Cependant tout le code du projet sera disponible sur Github en fin d’article.

Le code de notre ViewModel

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Timeline.Models;

namespace Timeline.ViewModels
{
    public class TimelineViewModel : BaseViewModel
    {
        public TimelineViewModel()
        {
            Title = "Timeline";
            TimelineEvents = new ObservableCollection<Event>
                (Services.EventService.GetAllEvents());
        }


        private ObservableCollection<Event> _timelineEvents;
        public ObservableCollection<Event> TimelineEvents
        {
            get { return _timelineEvents; }
            set { SetProperty(ref _timelineEvents, value); }
        }
    }
}

Le code de notre vue

Le défit qui nous fait face est de pouvoir relier sur notre UI, une ligne verticale à une image en cercle.

Deux Views nous permettra de faire cela :

  • Une BoxView pour la ligne verticale
  • Un ff:CachedImage pour l’image en cercle.

Le code complet:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="Timeline.Views.TimelineView"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:ff="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
    xmlns:ffTransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
    xmlns:viewModel="clr-namespace:Timeline.ViewModels"
    Title="{Binding Title}"
    BackgroundImage="bg.jpg">

    <ContentPage.BindingContext>
        <viewModel:TimelineViewModel />
    </ContentPage.BindingContext>

    <ContentPage.Content>
        <StackLayout>
            <ListView
                CachingStrategy="RecycleElement"
                HasUnevenRows="False"
                ItemsSource="{Binding TimelineEvents}"
                RowHeight="107"
                SelectionMode="None"
                SeparatorColor="Gray"
                SeparatorVisibility="None">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout
                                Margin="20,0,0,0"
                                Orientation="Horizontal"
                                VerticalOptions="Center">
                                <StackLayout
                                    x:Name="firstStackLayout"
                                    Margin="0,0,0,-6"
                                    HorizontalOptions="Center"
                                    Orientation="Vertical"
                                    VerticalOptions="Center">
                                    <BoxView
                                        Grid.Row="0"
                                        Grid.Column="0"
                                        Margin="0,0,0,-6"
                                        HeightRequest="30"
                                        HorizontalOptions="Center"
                                        WidthRequest="3"
                                        Color="Accent" />
                                    <ff:CachedImage
                                        Grid.Row="1"
                                        Grid.Column="0"
                                        Margin="0,0,0,0"
                                        HeightRequest="55"
                                        Source="{Binding AuthorImage}"
                                        WidthRequest="55">
                                        <ff:CachedImage.Transformations>
                                            <ffTransformations:RoundedTransformation
                                                BorderHexColor="#FF4081"
                                                BorderSize="20"
                                                Radius="240" />
                                        </ff:CachedImage.Transformations>
                                    </ff:CachedImage>
                                    <BoxView
                                        Grid.Row="2"
                                        Grid.Column="0"
                                        Margin="0,-6,0,0"
                                        HeightRequest="30"
                                        HorizontalOptions="Center"
                                        WidthRequest="3"
                                        Color="Accent" />
                                </StackLayout>
                                <StackLayout
                                    Margin="5,0,0,0"
                                    HorizontalOptions="FillAndExpand"
                                    Orientation="Horizontal"
                                    VerticalOptions="Center">
                                    <StackLayout
                                        Margin="0,0,5,0"
                                        HorizontalOptions="Start"
                                        Orientation="Vertical"
                                        VerticalOptions="Center">
                                        <Label
                                            FontAttributes="Bold"
                                            FontSize="15"
                                            HorizontalOptions="Start"
                                            Text="{Binding Title}"
                                            TextColor="Accent"
                                            XAlign="Start" />
                                        <StackLayout
                                            Margin="0,0,5,0"
                                            Orientation="Horizontal"
                                            VerticalOptions="EndAndExpand">
                                            <Label
                                                FontSize="14"
                                                Text="{Binding Detail}"
                                                TextColor="#4e5156" />
                                        </StackLayout>
                                        <StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand">
                                            <Label
                                                FontAttributes="Bold"
                                                FontSize="12"
                                                Text="{Binding DateToString}"
                                                TextColor="#3b0999" />
                                        </StackLayout>
                                    </StackLayout>
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Ressources

Voir le Code source sur Github.

N’hésitez pas à me contacter via le formulaire de contact ou par ou par mail.


Commentaires