• laurent@lioncoding.com

WhatsApp UI dans Xamarin.Forms (Partie 2)


👉 https://github.com/egbakou/WhatsAppUI le lien vers le projet complet sur Github.

Dans cette deuxième partie de la série d’articles “Concevoir les UI de WhatsApp dans Xamarin.Forms” il sera question de:

  • [x] Mettre en place le Model des contacts;
  • [x] Produire une source de données pour alimenter l’UI CHATS;
  • [x] Concevoir l’UI proprement dit;
  • [x] Créer le popup Page de visualisation des profils.

Le Model Contact

namespace WhatsApp.Models
{
    /// <summary>
    /// WhastSapp Contact class.
    /// ChatMetaData is the last message, date, ... with the currrent contact.
    /// </summary>
    public class Contact
    {
        public long ContactID { get; set; }
        public string PhoneNumber { get; set; }
        public string Name { get; set; }
        public string ProfileImage { get; set; }
        public bool ChatPinned { get; set; }
        public virtual LastChatMetaData ChatMetaData { get; set; }
    }
}

Le service qui nous fournira la liste des contacts

using System.Collections.Generic;
using WhatsApp.Models;

namespace WhatsApp.Services
{
    public class ContactService
    {
        public static List<Contact> GetAllContact()
        {
            List<Contact> contacts = new List<Contact>
            {              
                new Contact
                {
                    ContactID = 3,
                    Name = "Flora",
                    PhoneNumber = "+228999999",
                    ProfileImage = "Flora.jpg",
                    ChatPinned = true,
                    ChatMetaData = new LastChatMetaData{
                        LastChatMetaDataID = 1,
                        LastChatDatetime = "Yesterday",
                        MessageIsFromMe = true,
                        MessageContent = new Emoji(new int[] { 0x1F468, 0x200D, 0x1F4BB }).ToString()+" Xamarin.Forms"
                    }
                },
                new Contact
                {
                    ContactID = 4,
                    Name = "Rita",
                    PhoneNumber = "+228999999",
                    ProfileImage = "Rita.jpg",
                    ChatPinned = true,
                    ChatMetaData = new LastChatMetaData{
                        LastChatMetaDataID = 2,
                        LastChatDatetime = "23:12",
                        MessageIsFromMe = true,
                        MessageContent = "It&apos;s time to go !"
                    }
                }

            return contacts;
        }
    }
}

Le lien vers le code source complet de ce service.

NB: Une classe Emoji a été mise en place pour l’utilisation des Emojis dans les messages de Chat. Un de mes articles précédents vous montre comment utiliser des Emojis dans Xamarin.Forms.

L’UI de Chat

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="WhatsApp.Views.ChatsView"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:WhatsApp.Controls"
    xmlns:template="clr-namespace:WhatsApp.Views.Templates"
    xmlns:viewModel="clr-namespace:WhatsApp.ViewModels"
    Title="{Binding Title}">


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


    <ContentPage.Content>
        <RelativeLayout Margin="10,5,0,0">
            <ContentView RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
                <ListView
                    CachingStrategy="RecycleElement"
                    HasUnevenRows="False"
                    ItemTapped="ListView_ItemTapped"
                    ItemsSource="{Binding Contacts}"
                    RowHeight="75"
                    SelectionMode="None"
                    SeparatorColor="Gray"
                    SeparatorVisibility="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <!-- TEMPLATE -->
                                <template:ChatsViewTemplate />
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </ContentView>
            <!-- FLOAT ACTION BUTTON -->
            <controls:FloatingActionButton
                x:Name="FAB"
                Margin="0,0,5,5"
                ButtonColor="#2ECC71"
                Clicked="Button_Clicked"
                Image="bubble.png"
                RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                  Property=Width,
                                                                  Factor=1,
                                                                  Constant=-90}"
                RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                  Property=Height,
                                                                  Factor=1,
                                                                  Constant=-90}" />
        </RelativeLayout>
    </ContentPage.Content>
</ContentPage>

Le template du ViewCell

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="WhatsApp.Views.Templates.ChatsViewTemplate"
    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">
    <ContentView.Content>
        <StackLayout Orientation="Horizontal">
            <StackLayout
                HorizontalOptions="Center"
                Orientation="Vertical"
                VerticalOptions="Center">
                <ff:CachedImage
                    HeightRequest="55"
                    HorizontalOptions="StartAndExpand"
                    Source="{Binding ProfileImage}"
                    VerticalOptions="Center"
                    WidthRequest="55">
                    <ff:CachedImage.Transformations>
                        <ffTransformations:RoundedTransformation Radius="240" />
                    </ff:CachedImage.Transformations>
                    <ff:CachedImage.GestureRecognizers>
                        <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="TapGestureRecognizer_Tapped" />
                    </ff:CachedImage.GestureRecognizers>
                </ff:CachedImage>
            </StackLayout>
            <StackLayout
                Margin="10,0,0,0"
                HorizontalOptions="FillAndExpand"
                Orientation="Vertical"
                VerticalOptions="Center">
                <StackLayout
                    Margin="0,0,10,0"
                    HorizontalOptions="FillAndExpand"
                    Orientation="Horizontal"
                    VerticalOptions="Center">
                    <Label
                        Margin="0,0,0,0"
                        FontSize="17"
                        HorizontalOptions="Start"
                        Text="{Binding Name}"
                        TextColor="#000000"
                        XAlign="Start" />
                    <Label
                        FontSize="12"
                        HorizontalOptions="EndAndExpand"
                        Text="{Binding ChatMetaData.LastChatDatetime}"
                        TextColor="Gray"
                        XAlign="End" />
                </StackLayout>
                <StackLayout
                    Margin="0,0,10,10"
                    HorizontalOptions="FillAndExpand"
                    Orientation="Horizontal"
                    VerticalOptions="Center">
                    <Image
                        HeightRequest="15"
                        HorizontalOptions="Start"
                        IsVisible="{Binding ChatMetaData.MessageIsFromMe}"
                        Source="tick.png" />
                    <Label
                        FontSize="15"
                        HorizontalOptions="Start"
                        Text="{Binding ChatMetaData.MessageContent}"
                        TextColor="Gray"
                        XAlign="Start" />
                    <Image
                        HeightRequest="20"
                        HorizontalOptions="EndAndExpand"
                        IsVisible="{Binding ChatPinned}"
                        Source="pins.png"
                        WidthRequest="20" />
                </StackLayout>
                <StackLayout
                    Margin="0,0,10,0"
                    HorizontalOptions="FillAndExpand"
                    Orientation="Horizontal"
                    VerticalOptions="Center">
                    <BoxView
                        HeightRequest="0.3"
                        HorizontalOptions="FillAndExpand"
                        Color="LightGray" />
                </StackLayout>
            </StackLayout>
        </StackLayout>
    </ContentView.Content>
</ContentView>

Le popup Page de visualisation des profils

<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage
    x:Class="WhatsApp.PopupPages.ChatProfileSelectionPopupView"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
    xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">

    <pages:PopupPage.Animation>
        <animations:ScaleAnimation
            DurationIn="300"
            DurationOut="300"
            EasingIn="SinOut"
            EasingOut="SinIn"
            HasBackgroundAnimation="True"
            PositionIn="Center"
            PositionOut="Center"
            ScaleIn="1.2"
            ScaleOut="0.8" />
    </pages:PopupPage.Animation>

    <pages:PopupPage.Content>
        <Grid
            BackgroundColor="#fff"
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <StackLayout>
                <StackLayout
                    HeightRequest="250"
                    Orientation="Vertical"
                    VerticalOptions="Start"
                    WidthRequest="250">
                    <AbsoluteLayout>
                        <Image
                            AbsoluteLayout.LayoutBounds="1,1,1,1"
                            AbsoluteLayout.LayoutFlags="All"
                            Aspect="AspectFill"
                            Source="{Binding SelectedProfileImage}" />
                        <AbsoluteLayout
                            x:Name="ViewControls"
                            AbsoluteLayout.LayoutBounds="1,1,1,1"
                            AbsoluteLayout.LayoutFlags="All"
                            BackgroundColor="#66000000"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="Start">
                            <StackLayout
                                BackgroundColor="Transparent"
                                HeightRequest="35"
                                HorizontalOptions="FillAndExpand"
                                Orientation="Vertical">
                                <Label
                                    Margin="5,0,0,0"
                                    FontSize="Medium"
                                    HorizontalOptions="StartAndExpand"
                                    Text="{Binding Contact}"
                                    TextColor="White"
                                    VerticalOptions="CenterAndExpand" />
                            </StackLayout>
                        </AbsoluteLayout>
                    </AbsoluteLayout>
                </StackLayout>
                <StackLayout HeightRequest="30" HorizontalOptions="FillAndExpand">
                    <Grid HorizontalOptions="FillAndExpand">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="30" />
                        </Grid.RowDefinitions>

                        <Image
                            Grid.Row="0"
                            Grid.Column="0"
                            HeightRequest="25"
                            HorizontalOptions="Center"
                            Source="chat.png"
                            VerticalOptions="Center"
                            WidthRequest="25" />
                        <Image
                            Grid.Row="0"
                            Grid.Column="1"
                            HeightRequest="25"
                            HorizontalOptions="Center"
                            Source="voicecall.png"
                            VerticalOptions="Center"
                            WidthRequest="25" />
                        <Image
                            Grid.Row="0"
                            Grid.Column="2"
                            HeightRequest="25"
                            HorizontalOptions="Center"
                            Source="videocall.png"
                            VerticalOptions="Center"
                            WidthRequest="25" />
                        <Image
                            Grid.Row="0"
                            Grid.Column="3"
                            HeightRequest="25"
                            HorizontalOptions="Center"
                            Source="info.png"
                            VerticalOptions="Center"
                            WidthRequest="25" />
                    </Grid>
                </StackLayout>
            </StackLayout>

        </Grid>


    </pages:PopupPage.Content>
</pages:PopupPage>

Dans la partie suivante, nous mettrons en place l’interface des Statuts.

Ressources

👉 https://github.com/egbakou/WhatsAppUI le lien vers le projet complet sur Github.


Commentaires