Xamarin.Forms CollectionView レイアウト

サンプルのダウンロードサンプルのダウンロード

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

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

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

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

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

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

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

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

クラスは LinearItemsLayout クラスをItemsLayout継承し、 型doubleの プロパティをItemSpacing定義します。これは、各項目の周囲の空の領域を表します。 このプロパティの既定値は 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>

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

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

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

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

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

iOS および Android CollectionView の CollectionView 垂直リスト レイアウトのスクリーンショット

水平リスト

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 つの行リストが作成され、新しい項目が追加されると水平方向に大きくなります。

CollectionView 水平リスト レイアウトのスクリーンショット(iOS および 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>

または、このレイアウトは、 プロパティを ItemsLayout プロパティが に設定されているオブジェクトOrientationGridItemsLayout設定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 列のグリッドが作成され、新しい項目が追加されると垂直方向に拡大します。

iOS および Android CollectionView 垂直グリッド レイアウトの CollectionView 垂直スクリーンショット

水平グリッド

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>

または、このレイアウトは、 プロパティを ItemsLayout プロパティが に設定されているオブジェクトOrientationGridItemsLayout設定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 行のグリッドが作成され、新しい項目が追加されると水平方向に拡大します。

CollectionView 水平グリッド レイアウトのスクリーンショット(iOS および Android)

ヘッダーとフッター

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

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

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

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

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

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

<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 のスクリーンショットにフッターが表示されます。

iOS および Android CollectionView 文字列ヘッダーとフッターの CollectionView 文字列ヘッダーとフッタースクリーンショット

Headerプロパティと Footer プロパティはそれぞれビューに設定できます。 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 のスクリーンショットにフッターが表示されます。

iOS および Android CollectionView ビューのヘッダーとフッターのビューを使用した CollectionView ヘッダー

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 のスクリーンショットにフッターが表示されます。

iOS および Android CollectionView テンプレートヘッダーとフッターのテンプレートを使用した CollectionView ヘッダーとフッター

アイテムの間隔

既定では、 内の各項目の間に CollectionViewスペースはありません。 この動作は、 で使用される項目レイアウトのプロパティを設定することで CollectionView変更できます。

CollectionViewプロパティを ItemsLayout オブジェクトに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 列のリストになります。

iOS と Android の CollectionView 項目の間隔を含む CollectionView

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

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

注意

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

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

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

このコードでは、項目間の垂直方向の間隔が 20、項目間の水平方向の間隔が 30 の垂直方向の 2 列グリッドが作成されます。

間隔 Android CollectionView の項目間隔を含む CollectionView

アイテムのサイズ設定

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

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

重要

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

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

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

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

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

アイテムの動的なサイズ変更

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

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

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

iOS および Android CollectionView の動的な項目のサイズ設定を含む

右から左へのレイアウト

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 からプロパティ値をFlowDirectionStackLayout継承し、 からプロパティ値をFlowDirectionContentPage継承します。 これにより、次のスクリーンショットに示す右から左のレイアウトが表示されます。

CollectionView の右から左への垂直リスト レイアウトのスクリーンショット。iOS および Android

フローの方向の詳細については、「 右から左へのローカライズ」を参照してください。