Monday, 27 April 2020

Xamarin.Forms 4.0 CollectionView_Experimental

As part of the upcoming Xamarin.Forms 4.0 release, we are implementing the all new CollectionView control. The CollectionView is intended to be a successor to the ListView, improving upon its design by reducing technical complexity and allowing for more flexibility of layout and function. But we’re not stopping there! Along with this also comes the long-awaited CarouselView.
Technical note: Enable the CollectionView (which also enables the CarouselView) with a feature flag just before you initialize Xamarin.Forms in your MainActivity.cs and AppDelegate:
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
Follow along: if you wish to follow along with this blog post you can clone and run the sample from GitHub. Alternatively, if you want to update an existing project to the Xamarin.Forms 4.0-pre NuGet (available via your favorite NuGet package manager using the pre-release option).

A Basic Layout

One of the biggest changes between ListView and CollectionView is the removal of wrapping content in a ViewCell. This allows for significant gains to performance, especially on Android, while remaining familiar to what you’ve done before when using the ListView.
Below is an example layout. For simplicity’s sake, create a List<string> of people’s names in your binding context and then bind to it in XAML:
<StackLayout>
    <CollectionView x:Name="CV" 
                    ItemsSource="{Binding People}" 
                    Margin="10,0,0,0">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout HeightRequest="50" WidthRequest="200" Orientation="Horizontal" Padding="0,5,0,5">
                    <Image Source="person"/>
                    <Label Text="{Binding}" VerticalOptions="Center"/>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

A Basic CollectionView
Add caption
You now have a basic list of items. Notice that you no longer use a ViewCell, but a DataTemplate! Hopefully, so far this new CollectionView is familiar to the ListView you’ve used in the past. Let’s look now at what else it can do.

Making A Grid Layout

By default, CollectionView assumes a linear layout. That means you can not only do vertical lists, but horizontal as well! This is accomplished by setting the ItemsLayout property to a new instance of ListItemsLayout which takes an ItemsLayoutOrientation parameter (Vertical|Horizontal).
There’s also another option available: the GridItemsLayout.
Going back to the previous example above, you can use this option to make the CollectionView look a little fancier. Using a GridItemsLayout, you still get a scrollable list, but now with two items in each row:
  <StackLayout>
      <CollectionView x:Name="CV" ItemsSource="{Binding People}" VerticalOptions="Center" HorizontalOptions="Center" Margin="10,0,10,0">
          <CollectionView.ItemsLayout>
              <GridItemsLayout Orientation="Horizontal" Span="2"/>
          </CollectionView.ItemsLayout>
          <CollectionView.ItemTemplate>
              <DataTemplate>
                  <Frame BorderColor="LightGray" CornerRadius="3" HasShadow="False">
                      <Grid>
                          <Grid.ColumnDefinitions>
                              <ColumnDefinition Width="Auto"/>
                              <ColumnDefinition Width="100" />
                          </Grid.ColumnDefinitions>
                          <Grid.RowDefinitions>
                              <RowDefinition Height="Auto"/>
                          </Grid.RowDefinitions>
                          <Image Grid.Column="0" Source="person" Aspect="Fill"/>
                          <StackLayout Grid.Column="1">
                              <Label Text="{Binding}" HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand"/>
                          </StackLayout>
                      </Grid>
                  </Frame>
              </DataTemplate>
          </CollectionView.ItemTemplate>
      </CollectionView>
  </StackLayout>
Note the ItemsLayout in the above XAML. Setting the Orientation to Vertical indicates the direction in which the CollectionView expands, and the Span property sets the number of items per row. In this instance, when you choose to display two you get this result:
A Grid-style CollectionView

CarouselView is Here

The previous example shows a scrollable grid of people, but perhaps you want to show one person at a time in a card format. You can use CarouselView, a separate control which uses CollectionView as its basis, can be used to adjust your layout, and add in some business card-like information:
<CarouselView   x:Name="CV" 
                ItemsSource="{Binding People}" 
                HeightRequest="200" 
                HorizontalOptions="Center" 
                VerticalOptions="CenterAndExpand" 
                Margin="10">
    <CarouselView.ItemsLayout>
        <GridItemsLayout Orientation="Horizontal"/>
    </CarouselView.ItemsLayout>
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <Frame BorderColor="LightGray" CornerRadius="3" HasShadow="False">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="75"/>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Image Grid.Column="0" Grid.Row="0" Source="person" VerticalOptions="Start"/>
                    <StackLayout Grid.Column="1" Grid.Row="1" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand">
                        <Label Text="{Binding}" FontSize="24" HorizontalOptions="EndAndExpand"/>
                        <Label Text="Company Address" HorizontalOptions="EndAndExpand"/>
                        <Label Text="City, State" HorizontalOptions="EndAndExpand"/>
                    </StackLayout>
                </Grid>
            </Frame>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>

A page using a CarouselView

It’s a Snap to Use

One of the great features provided by CollectionView is the ability to add snap points. For the page you just designed, it allows for the view to stop part-way between cards. What if you instead want only one card to appear centered at a time? With the SnapPointsAlignment and SnapPointsType properties on the ItemsLayout, you can configure this behavior in a snap (pun intended)! Add the following to your XAML for enabling this behavior:
<CarouselView.ItemsLayout>
    <GridItemsLayout 
        Orientation="Horizontal" 
        SnapPointsAlignment="Center" 
        SnapPointsType="Mandatory"/>
</CarouselView.ItemsLayout>

A CarouselView using a SnapPoint

It’s so Empty in Here

Lastly, a common scenario many developers may face is what to display when the ItemsSource is empty. With the CollectionView you can now set any content to the EmptyView  of your list for just this purpose. With the XAML below, the string “No items currently exist!” will be shown inside of the CollectionView when the list of people is empty:
<CollectionView.EmptyView>
    <Label Text="No items currently exist!"/>
</CollectionView.EmptyView>

An EmptyView

You can customize this view however you like, including interactive content and supporting bindings.

No comments:

Post a Comment

All About .NET MAUI

  What’s .NET MAUI? .NET MAUI (.NET Multi-platform App UI) is a framework for building modern, multi-platform, natively compiled iOS, Androi...

Ads2