Xamarin.Forms CollectionView レイアウト
CollectionView
は、レイアウトを制御する次のプロパティを定義します。
ItemsLayout
型IItemsLayout
の 。 は、使用するレイアウトを指定します。ItemSizingStrategy
型ItemSizingStrategy
の 。 は、使用する項目メジャー戦略を指定します。
これらのプロパティは オブジェクトによって BindableProperty
サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。
既定では、 CollectionView
は項目を垂直リストに表示します。 ただし、次のいずれかのレイアウトを使用できます。
- 縦書きリスト – 新しい項目が追加されると垂直方向に拡大する 1 つの列リスト。
- 水平リスト – 新しい項目が追加されると水平方向に拡大する 1 つの行リスト。
- 垂直グリッド – 新しい項目が追加されると垂直方向に拡大する複数列のグリッド。
- 水平グリッド – 新しい項目が追加されると水平方向に拡大する複数行のグリッド。
これらのレイアウトは、 プロパティを ItemsLayout
クラスから ItemsLayout
派生したクラスに設定することで指定できます。 このクラスでは、次のプロパティが定義されています。
Orientation
型ItemsLayoutOrientation
の 。 は、項目が追加される際に をCollectionView
展開する方向を指定します。SnapPointsAlignment
型SnapPointsAlignment
の 。 は、スナップ ポイントと項目の配置方法を指定します。SnapPointsType
型SnapPointsType
の 。 は、スクロール時のスナップ ポイントの動作を指定します。
これらのプロパティは オブジェクトによって 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
指定Vertical
ItemsLayoutOrientation
することで、これを実現することもできます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
...
</CollectionView>
これに相当する C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Vertical
};
これにより、1 つの列リストが作成され、新しい項目が追加されると垂直方向に大きくなります。
水平リスト
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
値として指定することでItemsLayoutOrientation
Horizontal
、このレイアウトをOrientation
実現することもできます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
これに相当する C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Horizontal
};
これにより、1 つの行リストが作成され、新しい項目が追加されると水平方向に大きくなります。
垂直グリッド
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
プロパティが に設定されているオブジェクトOrientation
にGridItemsLayout
設定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 列のグリッドが作成され、新しい項目が追加されると垂直方向に拡大します。
水平グリッド
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
プロパティが に設定されているオブジェクトOrientation
にGridItemsLayout
設定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
リスト内の項目と共にスクロールするヘッダーとフッターを表示できます。 ヘッダーとフッターには、文字列、ビュー、または DataTemplate
オブジェクトを指定できます。
CollectionView
は、ヘッダーとフッターを指定するための次のプロパティを定義します。
Header
型object
の は、リストの先頭に表示される文字列、バインド、またはビューを指定します。HeaderTemplate
型DataTemplate
の は、DataTemplate
の書式を設定するために使用する を指定しますHeader
。Footer
の型object
は、リストの末尾に表示される文字列、バインド、またはビューを指定します。FooterTemplate
型DataTemplate
の は、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 のスクリーンショットにフッターが表示されます。
ヘッダーとフッターにビューを表示する
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 のスクリーンショットにフッターが表示されます。
テンプレート化されたヘッダーとフッターを表示する
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 のスクリーンショットにフッターが表示されます。
アイテムの間隔
既定では、 内の各項目の間に 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 列のリストになります。
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 列グリッドが作成されます。
アイテムのサイズ設定
既定では、 の 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
実行され、画像のサイズが変更され、表示が容易になります。
右から左へのレイアウト
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
からプロパティ値をFlowDirection
StackLayout
継承し、 からプロパティ値をFlowDirection
ContentPage
継承します。 これにより、次のスクリーンショットに示す右から左のレイアウトが表示されます。
フローの方向の詳細については、「 右から左へのローカライズ」を参照してください。