Xamarin.Forms CollectionView レイアウト

Download Sample サンプルをダウンロードします

CollectionView は、レイアウトを制御する次のプロパティを定義します。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。

既定では、a CollectionView は項目を縦一覧に表示します。 ただし、次のいずれかのレイアウトを使用できます。

  • 縦書きリスト – 新しい項目が追加されると垂直方向に大きくなる 1 つの列リスト。
  • 水平リスト – 新しい項目が追加されると水平方向に拡大する 1 つの行リスト。
  • 垂直グリッド – 新しい項目が追加されると垂直方向に拡大する複数列グリッド。
  • 水平グリッド – 新しい項目が追加されると水平方向に拡大する複数行グリッド。

これらのレイアウトは、プロパティを ItemsLayout クラスから ItemsLayout 派生するクラスに設定することで指定できます。 このクラスでは、次のプロパティが定義されています。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。 スナップ点の詳細については、「CollectionView スクロール ガイド」Xamarin.Forms「スナップポイント」を参照してください。

ItemsLayoutOrientation 列挙体を使って、次のメンバーを定義できます。

  • Vertical は、項目が CollectionView 追加されると垂直方向に展開されることを示します。
  • Horizontal は、項目が CollectionView 追加されると水平方向に展開されることを示します。

クラスは LinearItemsLayout クラスから継承し、各項目の ItemsLayout 周囲の空き領域を ItemSpacing 表す型 doubleのプロパティを定義します。 このプロパティの既定値は 0 で、その値は常に 0 以上である必要があります。 このクラスは LinearItemsLayout 、静的 Vertical メンバーと Horizontal メンバーも定義します。 これらのメンバーは、それぞれ縦または横のリストを作成するために使用できます。 または、列挙メンバーを LinearItemsLayout 引数として指定して、オブジェクトを ItemsLayoutOrientation 作成することもできます。

クラスは GridItemsLayout クラスを ItemsLayout 継承し、次のプロパティを定義します。

  • VerticalItemSpacingは、各項目の周囲の垂直方向の空き領域を表す型 doubleです。 このプロパティの既定値は 0 で、その値は常に 0 以上である必要があります。
  • HorizontalItemSpacingの種類 double。各項目の周囲の水平方向の空き領域を表します。 このプロパティの既定値は 0 で、その値は常に 0 以上である必要があります。
  • Span: 型 int。グリッドに表示する列または行の数を表します。 このプロパティの既定値は 1 で、その値は常に 1 以上である必要があります。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。

注意

CollectionView では、ネイティブ レイアウト エンジンを使用してレイアウトを実行します。

縦書きリスト

既定では、 CollectionView 項目は縦書きのリスト レイアウトで表示されます。 したがって、このレイアウトを使用するようにプロパティを ItemsLayout 設定する必要はありません。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

ただし、完成度を高めるために、XAML CollectionView では、プロパティを次のように設定することで、項目を垂直リストに表示するようにVerticalList設定ItemsLayoutできます。

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="VerticalList">
    ...
</CollectionView>

または、プロパティをオブジェクトに設定し、列挙メンバーをItemsLayoutLinearItemsLayoutプロパティ値としてOrientation指定することでVerticalItemsLayoutOrientation、これを実現することもできます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Vertical
};

これにより、1 つの列リストが作成され、新しい項目が追加されると垂直方向に増加します。

Screenshot of a CollectionView vertical list layout, on iOS and Android

水平リスト

XAML では、プロパティを CollectionView 次に設定 ItemsLayout することで、項目を水平リストに HorizontalList表示できます。

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="HorizontalList">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="140" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

または、プロパティをオブジェクトに設定し、列挙メンバーをItemsLayoutプロパティLinearItemsLayout値として指定することでItemsLayoutOrientationHorizontal、このレイアウトをOrientation実現することもできます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Horizontal
};

これにより、1 つの行リストが作成され、新しい項目が追加されると水平方向に大きくなります。

Screenshot of a CollectionView horizontal list layout, on iOS and Android

垂直グリッド

XAML では、プロパティを CollectionView 次に設定 ItemsLayout することで、項目を垂直グリッドに VerticalGrid表示できます。

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="VerticalGrid, 2">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

または、プロパティを次のように設定したオブジェクトOrientationにプロパティをItemsLayoutGridItemsLayout設定することで、このレイアウトをVertical実現することもできます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};

既定では、縦書 GridItemsLayout きでは 1 つの列に項目が表示されます。 ただし、この例では、プロパティを GridItemsLayout.Span 2 に設定します。 これにより、2 列のグリッドが作成され、新しい項目が追加されると垂直方向に拡大します。

Screenshot of a CollectionView vertical grid layout, on iOS and Android

水平グリッド

XAML では、プロパティを CollectionView 次に設定 ItemsLayout することで、項目を水平グリッドに HorizontalGrid表示できます。

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="HorizontalGrid, 4">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="140" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

または、プロパティを次のように設定したオブジェクトOrientationにプロパティをItemsLayoutGridItemsLayout設定することで、このレイアウトをHorizontal実現することもできます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Horizontal"
                        Span="4" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};

既定では、水平方向 GridItemsLayout のアイテムは 1 行に表示されます。 ただし、この例では、プロパティを GridItemsLayout.Span 4 に設定します。 これにより、4 行のグリッドが作成され、新しい項目が追加されると水平方向に拡大します。

Screenshot of a CollectionView horizontal grid layout, on iOS and Android

ヘッダーとフッター

CollectionView では、リスト内の項目と共にスクロールするヘッダーとフッターを表示できます。 ヘッダーとフッターには、文字列、ビュー、またはオブジェクトを指定 DataTemplate できます。

CollectionView は、ヘッダーとフッターを指定するための次のプロパティを定義します。

  • Headerの型 objectは、リストの先頭に表示される文字列、バインド、またはビューを指定します。
  • HeaderTemplateの型 DataTemplateは、書式を DataTemplate 設定するために使用するオブジェクトを Header指定します。
  • Footerの型 objectは、リストの末尾に表示される文字列、バインド、またはビューを指定します。
  • FooterTemplateの型 DataTemplateは、書式を DataTemplate 設定するために使用するオブジェクトを Footer指定します。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。

左右に拡大するレイアウトにヘッダーを追加すると、ヘッダーが一覧の左側に表示されます。 同様に、左右に拡大するレイアウトにフッターを追加すると、フッターがリストの右側に表示されます。

次のHeader例にstring示すように、値とFooterプロパティを値に設定できます。

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="Monkeys"
                Footer="2019">
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    Header = "Monkeys",
    Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

このコードでは、次のスクリーンショットが表示され、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。

Screenshot of a CollectionView string header and footer, on iOS and Android

プロパティとFooterプロパティはそれぞれHeaderビューに設定できます。 1 つのビュー、または複数の子ビューを含むビューを指定できます。 次の例は、各セットがHeaderオブジェクトをStackLayout含むオブジェクトに設定されているプロパティとFooterプロパティをLabel示しています。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.Header>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Monkeys"
                   FontSize="Small"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Header>
    <CollectionView.Footer>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Friends of Xamarin Monkey"
                   FontSize="Small"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Footer>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    Header = new StackLayout
    {
        Children =
        {
            new Label { Text = "Monkeys", ... }
        }
    },
    Footer = new StackLayout
    {
        Children =
        {
            new Label { Text = "Friends of Xamarin Monkey", ... }
        }
    }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

このコードでは、次のスクリーンショットが表示され、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。

Screenshot of a CollectionView header and footer using views, on iOS and Android

プロパティとプロパティは HeaderTemplate 、ヘッダーと FooterTemplate フッターの書式設定に使用されるオブジェクトに設定 DataTemplate できます。 このシナリオでは、次の Header 例に示すように、テンプレートを適用するために、プロパティと Footer プロパティを現在のソースにバインドする必要があります。

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="{Binding .}"
                Footer="{Binding .}">
    <CollectionView.HeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Monkeys"
                       FontSize="Small"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.HeaderTemplate>
    <CollectionView.FooterTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Friends of Xamarin Monkey"
                       FontSize="Small"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.FooterTemplate>
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    HeaderTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    }),
    FooterTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    })
};
collectionView.SetBinding(ItemsView.HeaderProperty, ".");
collectionView.SetBinding(ItemsView.FooterProperty, ".");
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

このコードでは、次のスクリーンショットが表示され、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。

Screenshot of a CollectionView header and footer using templates, on iOS and Android

項目の間隔

既定では、 CollectionView. この動作は、で使用される項目レイアウトのプロパティを設定することによって CollectionView変更できます。

プロパティをCollectionViewItemsLayoutオブジェクトにLinearItemsLayout設定する場合、プロパティはLinearItemsLayout.ItemSpacing項目間のスペースをdouble表す値に設定できます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="20" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

注意

LinearItemsLayout.ItemSpacingプロパティには検証コールバック セットがあり、プロパティの値が常に 0 以上であることを保証します。

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        ItemSpacing = 20
    }
};

このコードは、項目間の間隔が 20 の縦 1 列のリストになります。

Screenshot of a CollectionView with item spacing, on iOS and Android

プロパティをCollectionViewItemsLayoutオブジェクトにGridItemsLayout設定すると、項目間のGridItemsLayout.VerticalItemSpacing垂直方向および水平方向のdouble空き領域を表す値とGridItemsLayout.HorizontalItemSpacingプロパティを設定できます。

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2"
                        VerticalItemSpacing="20"
                        HorizontalItemSpacing="30" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

注意

プロパティ GridItemsLayout.VerticalItemSpacingGridItemsLayout.HorizontalItemSpacing プロパティには検証コールバックが設定されており、プロパティの値が常に 0 以上であることを確認します。

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
    {
        VerticalItemSpacing = 20,
        HorizontalItemSpacing = 30
    }
};

このコードの結果、項目間の垂直方向の間隔は 20、項目間の水平方向の間隔は 30 の垂直方向の 2 列グリッドになります。

Screenshot of a CollectionView with item spacing, on Android

アイテムのサイズ設定

既定では、UI 要素DataTemplateで固定サイズが指定されていない場合、a CollectionView 内の各項目は個別に測定およびサイズ設定されます。 変更可能なこの動作は、プロパティ値によって CollectionView.ItemSizingStrategy 指定されます。 このプロパティ値は、列挙メンバーのいずれかに ItemSizingStrategy 設定できます。

  • MeasureAllItems – 各項目は個別に測定されます。 これが既定値です。
  • MeasureFirstItem – 最初の項目のみが測定され、後続のすべての項目に最初の項目と同じサイズが与えられます。

重要

サイズ設定戦略では MeasureFirstItem 、すべてのアイテムで項目のサイズが均一であることを意図している状況で使用すると、パフォーマンスが向上します。

次のコード例は、プロパティの設定を ItemSizingStrategy 示しています。

<CollectionView ...
                ItemSizingStrategy="MeasureFirstItem">
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ...
    ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};

項目の動的なサイズ変更

内の要素の CollectionView レイアウト関連プロパティを変更することで、実行時に項目のサイズを動的に DataTemplate変更できます。 たとえば、次のコード例では、オブジェクトの HeightRequest プロパティとプロパティ WidthRequestImage 変更します。

void OnImageTapped(object sender, EventArgs e)
{
    Image image = sender as Image;
    image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}

イベント ハンドラーは OnImageTapped 、タップされているオブジェクトに応答して Image 実行され、画像のサイズを変更して、より簡単に表示できるようにします。

Screenshot of a CollectionView with dynamic item sizing, on iOS and Android

右から左へのレイアウト

CollectionView を使用すると、プロパティを〘に設定 FlowDirection することで、コンテンツを右から左へのフロー方向に RightToLeftレイアウトできます。 ただし、 FlowDirection このプロパティは、ページまたはルート レイアウトに設定するのが理想的です。これにより、ページ内のすべての要素 (ルート レイアウト) がフローの方向に応答します。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CollectionViewDemos.Views.VerticalListFlowDirectionPage"
             Title="Vertical list (RTL FlowDirection)"
             FlowDirection="RightToLeft">
    <StackLayout Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}">
            ...
        </CollectionView>
    </StackLayout>
</ContentPage>

親を持つ要素の既定値FlowDirectionは .MatchParent したがって、CollectionViewプロパティの値StackLayoutFlowDirectionContentPageを継承します。FlowDirection これにより、次のスクリーンショットに示す右から左のレイアウトが表示されます。

Screenshot of a CollectionView right-to-left vertical list layout, on iOS and Android

フロー方向の詳細については、「 右から左へのローカリゼーション」を参照してください。