Xamarin.Forms 4.0 new features – CollectionView

On Connect(); 2018 Microsoft announced Xamarin.Forms 4.0 with some new interesting features like Shell, Visual, CollectionView and more. They are all amazing and I hope that I will have opportunity to write about them on this blog, but today we will take a closer look at CollectionView. This is new way introduced by Microsoft to manage the display of data collection. So far, in Xamarin.Forms, we had ListView and TableView to handle collections, but the main problem with them is that both ListView and TableView have performance issues. To fix this and provide new features for displaying data collections Microsoft has created CollectionView. In this post I want to show you how to use CollectionView in your Xamarin.Forms application.

Xamarin.Forms 4.0 is now in preview and the same applies to CollectionView, so you will have to do additional steps to use it. I’ve created simple Xamarin.Forms application called XamarinFormsCollectionViewSample. To use Xamarin.Forms 4.0 features we need to update Xamarin.Forms NuGet package to at least version 4.0.0.8055-pre1.

In platform projects before calling Forms.Init we need to set CollectionView_Experimental flag, otherwise CollectionView won’t work. Don’t forget to add it to iOS and Android project.

global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");

We are ready to use CollectionView in Xamarin.Forms page. I will add CollectionView to MainPage, same as in ListView we will have to add ItemTemplate with DataTemplate to set template view for each row.

<StackLayout>
   <StackLayout.Margin>
      <OnPlatform x:TypeArguments="Thickness" iOS="0, 40, 0, 0" />
   </StackLayout.Margin>
   <Label Text="Hamilton show actors"  FontSize="Medium" />
   <CollectionView>
      <CollectionView.ItemTemplate>
         <DataTemplate></DataTemplate>
      </CollectionView.ItemTemplate>
   </CollectionView>
</StackLayout>

As I mentioned at the beginning CollectionView is supposed to display collections of data. So this is the perfect time to create data template and add real data. This example will display list of actors from famous Hamilton show, this is my Actor class that I added to project.

public class Actor
{
    public string Name { get; set; }
    public string Plays { get; set; }
    public string Picture { get; set; }
}

In MainPage we will add property called Actors with list of all main actors of Hamilton show and then set Actors as BindingContext in MainPage constructor.

public List<Actor> Actors = new List<Actor>
{
    new Actor
    {
        Name = "Michael Luwoye",
        Plays = "Alexander Hamilton",
        Picture = "hamilton.jpg"
    },
    new Actor
    {
        Name = "Daniel Breaker",
        Plays = "Aaron Burr",
        Picture = "burr.jpg"
    },
    new Actor
    {
        Name = "Mandy Gonzalez",
        Plays = "Angelica Schuyler",
        Picture = "schuyler.jpg"
    },
    new Actor
    {
        Name = "Denée Benton",
        Plays = "Eliza",
        Picture = "eliza.jpg"
    },
    new Actor
    {
         Name = "Euan Morton",
         Plays = "King George",
         Picture = "george.jpg"
    },
    new Actor
    {
         Name = "James Monroe Iglehart",
         Plays = "Thomas Jefferson",
         Picture = "jefferson.jpg"
    },
    new Actor
    {
          Name = "Carvens Lissaint",
          Plays = "George Washington",
          Picture = "washington.jpg"
    },
    new Actor
    {
          Name = "Anthony Lee Medina",
          Plays = "Phillip Hamilton",
          Picture = "phamilton.jpg"
    },
    new Actor
    {
          Name = "Alysha Deslorieux",
          Plays = "Maria Reynolds",
          Picture = "reynolds.jpg"
    },
    new Actor
    {
          Name = "J. Quinton Johnson",
          Plays = "James Madison",
          Picture = "madison.jpg"
    }
};

public MainPage()
{
    BindingContext = Actors;
    InitializeComponent();
}

We also need to add actors images to Resources/drawable on Android project and to Assets.xcassets on iOS project.

It’s time to set Binding in CollectionView and update DataTemplate. Again, everything is the same as in ListView.

<CollectionView ItemsSource="{Binding .}">
   <CollectionView.ItemTemplate>
      <DataTemplate>
         <StackLayout Padding="10">
            <Image Source="{Binding Picture}" />
            <Label Text="{Binding Name}" Margin="0, 3" />
            <Label Text="{Binding Plays}" FontSize="11" />
         </StackLayout>
      </DataTemplate>
   </CollectionView.ItemTemplate>
</CollectionView>

When you start the application should look like this

The first new CollectionView feature is the ability to provide an empty view. To do this in CollectionView add EmptyView.

<CollectionView.EmptyView>
   <StackLayout>
      <Label Text="No results" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" />
   </StackLayout>
</CollectionView.EmptyView>

To see any changes, you have to remove binding or actors data.

In CollectionView, you can set layout to list or grid with vertical/horizontal orientation. Vertical list is default layout, but you can set it as follows

<CollectionView ItemsSource="{Binding .}" ItemsLayout="{x:Static ListItemsLayout.VerticalList}">

To change orientation to horizontal you have to set ItemsLayout to ListItemsLayout.HorizontalList and width and height for row template view

<CollectionView ItemsSource="{Binding .}" ItemsLayout="{x:Static ListItemsLayout.HorizontalList}">

This results in a single row list, which grows horizontally as new items are added:

The difference between list and grid layouts is that in grid we can add more than 1 column, to set grid with 2 columns and vertical orientation use this code

<CollectionView.ItemsLayout>
   <GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>

This results in 2 column grid, which grows vertically as new items are added:

We can also change orientation in grid layout to horizontal

<CollectionView.ItemsLayout>
   <GridItemsLayout Orientation="Horizontal" Span="2" />
</CollectionView.ItemsLayout>

This results in 2 column grid, which grows horizontally as new items are added:

In CollectionView we also have ability to set scrolling position using ScrollTo method, I leave checking this functionality to you.

Unfortunately, CollectionView is not only new features that are missing on ListView. In CollectionView you don’t have refreshing functionality, you must write your own refreshing mechanism or use already implemented controls such as PullToRefreshLayout by James Montemagno. The next feature that is missing in CollectionView is Header/Footer view and for now you can’t group data into sections. It’s possible that many of these things will be added in the final version, but you should consider if the lack of these functionalities will not affect your applications. In return, you’ll get quick lists that can be displayed in several columns and have empty view implemented. In the next post, I will compare speed of both approaches for displaying data collection. Source code for this example is on github.

CollectionView looks like pretty good change for Xamarin.Forms. Are you planning to turn your ListView into CollectionView in the future? Let me know in the comment!