Home

Awesome

CollectionView for Xamarin.Forms

This is a flexible ListView that has a grid and horizontal layout with reusable cells for Xamarin.Forms (Android / iOS).

Japanese

Build status

Available controls

Minimum Platform OS Version

iOS: iOS10
Android: version 5.1.1 (only FormsAppcompatActivity) / API22

Demo

<img src="images/SS_ios.jpg" height="800" /> <img src="images/SS_android.jpg" height="800" />

<a href="https://www.youtube.com/watch?feature=player_embedded&v=qF4sVnE5Dao " target="_blank"><img src="https://img.youtube.com/vi/qF4sVnE5Dao/0.jpg" alt="" width="480" height="360" border="0" /></a>

Get Started

Nuget Installation

https://www.nuget.org/packages/AiForms.CollectionView/

Install-Package AiForms.CollectionView -pre

You need to install this nuget package to .NETStandard project and each platform project.

For iOS project

To use on iOS, you need to write some code in AppDelegate.cs.

public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
    global::Xamarin.Forms.Forms.Init();

    AiForms.Renderers.iOS.CollectionViewInit.Init(); //need to write here

    LoadApplication(new App(new iOSInitializer()));

    return base.FinishedLaunching(app, options);
}

Using with XAML

For GridCollectionView

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:ai="clr-namespace:AiForms.Renderers;assembly=CollectionView"
    x:Class="Sample.Views.Test">
    <ai:GridCollectionView 
        ItemsSource="{Binding ItemsSource}" TouchFeedbackColor="Yellow"
        ColumnWidth="100" ColumnHeight="1.0" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ai:ContentCell>
                    <Label Text="{Binding Name}" />
                </ai:ContentCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ai:GridCollectionView>
</ContentPage>

For HCollectionView

    ...
    <ai:HCollectionView 
        ItemsSource="{Binding ItemsSource}" TouchFeedbackColor="Yellow"
        ColumnWidth="100" HeightRequest="100" Spacing="4" IsInfinite="true" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ai:ContentCell>
                    <Label Text="{Binding Name}" />
                </ai:ContentCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ai:HCollectionView>

For Grouped GridCollectionView

    ...
    <ai:GridCollectionView 
        ItemsSource="{Binding ItemsSource}" TouchFeedbackColor="Yellow"
        ColumnWidth="100" ColumnHeight="1.0"
        IsGroupingEnabled="true" GroupHeaderHeight="36"   >
        <ListView.GroupHeaderTemplate>
            <DataTemplate>
                <ai:ContentCell>
                    <Label Text="{Binding Category}" BackgroundColor="#E6DAB9" />
                </ai:ContentCell>
            </DataTemplate>
        </ListView.GroupHeaderTemplate>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ai:ContentCell>
                    <Label Text="{Binding Name}" />
                </ai:ContentCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ai:GridCollectionView>

How to setting a Grouped HCollectionView is the same as the abobe.

Note that the root of DataTemplate must be arranged not a ViewCell but a ContentCell.

A example of how to create grouped items source

public class PhotoGroup : ObservableCollection<PhotoItem>
{
    public string Head { get; set; }
    public PhotoGroup(IEnumerable<PhotoItem> list) : base(list) { }
}

public class PhotoItem
{
    public string PhotoUrl { get; set; }
    public string Title { get; set; }
    public string Category { get; set; }
}

public class SomeViewModel
{
    public ObservableCollection<PhotoGroup> ItemsSource { get; } = new ObservableCollection<PhotoGroup>();

    public SomeViewModel()
    {
        var list1 = new List<PhotoItem>();
        for (var i = 0; i < 20; i++)
        {
            list1.Add(new PhotoItem
            {
                PhotoUrl = $"https://example.com/{i + 1}.jpg",
                Title = $"Title {i + 1}",
                Category = "AAA",
            });
        }
        var list2 = new List<PhotoItem>();
        for (var i = 20; i < 40; i++)
        {
            list2.Add(new PhotoItem
            {
                PhotoUrl = $"https://example.com/{i + 1}.jpg",
                Title = $"Title {i + 1}",
                Category = "BBB",
            });
        }

        var group1 = new PhotoGroup(list1) { Head = "SectionA" };
        var group2 = new PhotoGroup(list2) { Head = "SectionB" };

        ItemsSource.Add(group1);
        ItemsSource.Add(group2);
    }
}

A example of how to use LoadMoreCommand and SetLoadMoreCompletion.

<ai:GridCollectionView 
    ItemsSource="{Binding ItemsSource}"
    LoadMoreCommand="{Binding LoadMoreCommand}"
    SetLoadMoreCompletion="{Binding SetLoadMoreCompletion}" >
    ...omitting
</ai:GridCollectionView>
public class SomeViewModel
{
    public ObservableCollection<Item> ItemsSource { get; } = new ObservableCollection<Item>();
    public Command LoadMoreCommand { get; set; }
    public Action<bool> SetLoadMoreCompletion { get; set; }

    public async Task LoadMoreCommandExecute()
    {
        var items = await WebApi.GetItems(10);

        if(items.Count == 0)
        {
            SetLoadMoreCompletion(true); // All the items was loaded.
            return;
        }

        foreach(var item in items)
        {
            ItemsSource.Add(item);
        }

        SetLoadMoreCompletion(false); // All the items is not still loaded.
    }
}

Available functions deriving from ListView

Bindable properties

Events

Methods

Caching Strategy

ListView's Caching Strategy is available for both GridCollectionView and HCollectionView. Note that ListView uses RetainElement by default but CollectionView uses RecycleElement.

Since ListViewCachingStrategy is not a property, it must be set using "x:Arguments" syntax from XAML for changing to the other value.

<ai:HCollectionView ...>
    <x:Arguments>
        <ListViewCachingStrategy>RetainElement</ListViewCachingStrategy>
    </x:Arguments>
    ...
</ai:HCollectionView>

Alternatively, it is set using code from C#.

var collectionView = new HCollectionView(ListViewCachingStrategy.RetainElement);

For images

If you use images for a data template item, using FFImageLoading is recommended powerfully. Because this library doesn't contain the feature of such as dealing with images asynchronously and caching.

Common Bindable Properties (GridCollectionView / HCollectionView)

GridCollectionView

This is the ListView that lays out each item in a grid pattern. Though this is similar to WrapLayout, is different from it in that cells can be recycled.

Bindable Properties

Special Properties

<a href="#gridtype"></a>GridType Enumeration

<a href="#spacingtype"></a>SpacingType Enumeration

HCollectionView

This is the ListView that lays out each item horizontally. This can make the scroll circulated by setting IsInfinite property to true. HCollectionView also recycles cells.

Bindable Properties

About Row Height

HCollectionView height is decided by the HeightRequest value or itself size.

<a href="#scrollcontroller"></a>ScrollController

This is the object which allows methods for scrolling to be called from such as ViewModel. The following code is the example calling ScrollTo method from ViewModel:

public class SomeViewModel
{
    public ObservableCollection<string> ItemsSource { get; } = new ObservableCollection<string>{ new List<string>{"A","B","C"} };
    public IScrollController ScrollController { get; set; }

    ...
    public GoToItem(int target)
    {
        // Scroll to the specified item position at the first visible area position with animation. If the target is 1, scroll to "B".
        ScrollController.ScrollTo(ItemsSource[target],ScrollToPosition.Start,true);
    }
    public GoToStart()
    {
        ScrollController.ScrollToStart(true); // scroll to "A" with animation
    }
    public GoToEnd()
    {
        ScrollController.ScrollToEnd(true); // scroll to "C" with animation
    }
}
<ai:GridCollectionView 
    ItemsSource="{Binding ItemsSource}"
    ScrollController="{Binding ScrollController}"
    ...
>
</ai:GridCollectionView>

IScrollController Methods

License

The MIT Licensed.

Some code is taken from Xamarin.Forms.