Xamarin.Forms CollectionView Layout
CollectionView
define as seguintes propriedades que controlam o layout:
ItemsLayout
, do tipoIItemsLayout
, especifica o layout a ser usado.ItemSizingStrategy
, do tipoItemSizingStrategy
, especifica a estratégia de medida de item a ser usada.
Essas propriedades são apoiadas por BindableProperty
objetos, o que significa que as propriedades podem ser destinos de associações de dados.
Por padrão, um CollectionView
exibirá seus itens em uma lista vertical. No entanto, qualquer um dos seguintes layouts pode ser usado:
- Lista vertical – uma única lista de colunas que cresce verticalmente à medida que novos itens são adicionados.
- Lista horizontal – uma única lista de linhas que cresce horizontalmente à medida que novos itens são adicionados.
- Grade vertical – uma grade de várias colunas que cresce verticalmente à medida que novos itens são adicionados.
- Grade horizontal – uma grade de várias linhas que cresce horizontalmente à medida que novos itens são adicionados.
Esses layouts podem ser especificados definindo a ItemsLayout
propriedade como classe derivada da ItemsLayout
classe . Essa classe define as seguintes propriedades:
Orientation
, do tipoItemsLayoutOrientation
, especifica a direção na qual oCollectionView
se expande à medida que os itens são adicionados.SnapPointsAlignment
, do tipoSnapPointsAlignment
, especifica como os pontos de ajuste são alinhados com os itens.SnapPointsType
, do tipoSnapPointsType
, especifica o comportamento dos pontos de ajuste ao rolar.
Essas propriedades são apoiadas por BindableProperty
objetos, o que significa que as propriedades podem ser destinos de associações de dados. Para obter mais informações sobre pontos de ajuste, consulte Pontos de ajuste no Xamarin.Forms guia rolagem CollectionView .
A enumeração ItemsLayoutOrientation
define os seguintes membros:
Vertical
indica que oCollectionView
se expandirá verticalmente à medida que os itens forem adicionados.Horizontal
indica que oCollectionView
se expandirá horizontalmente à medida que os itens forem adicionados.
A LinearItemsLayout
classe herda da ItemsLayout
classe e define uma ItemSpacing
propriedade, do tipo double
, que representa o espaço vazio em torno de cada item. O valor padrão dessa propriedade é 0 e seu valor sempre deve ser maior ou igual a 0. A LinearItemsLayout
classe também define membros e Horizontal
estáticosVertical
. Esses membros podem ser usados para criar listas verticais ou horizontais, respectivamente. Como alternativa, um LinearItemsLayout
objeto pode ser criado, especificando um ItemsLayoutOrientation
membro de enumeração como um argumento.
A GridItemsLayout
classe herda da ItemsLayout
classe e define as seguintes propriedades:
VerticalItemSpacing
, do tipodouble
, que representa o espaço vazio vertical em torno de cada item. O valor padrão dessa propriedade é 0 e seu valor sempre deve ser maior ou igual a 0.HorizontalItemSpacing
, do tipodouble
, que representa o espaço vazio horizontal em torno de cada item. O valor padrão dessa propriedade é 0 e seu valor sempre deve ser maior ou igual a 0.Span
, do tipoint
, que representa o número de colunas ou linhas a serem exibidas na grade. O valor padrão dessa propriedade é 1 e seu valor sempre deve ser maior ou igual a 1.
Essas propriedades são apoiadas por BindableProperty
objetos, o que significa que as propriedades podem ser destinos de associações de dados.
Observação
CollectionView
usa os mecanismos de layout nativos para executar o layout.
Lista vertical
Por padrão, CollectionView
exibirá seus itens em um layout de lista vertical. Portanto, não é necessário definir a ItemsLayout
propriedade para usar este layout:
<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>
No entanto, para integridade, em XAML um CollectionView
pode ser definido para exibir seus itens em uma lista vertical definindo sua ItemsLayout
propriedade como VerticalList
:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="VerticalList">
...
</CollectionView>
Como alternativa, isso também pode ser feito definindo a ItemsLayout
propriedade como um LinearItemsLayout
objeto, especificando o membro de Vertical
ItemsLayoutOrientation
enumeração como o valor da Orientation
propriedade:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Vertical
};
Isso resulta em uma única lista de colunas, que cresce verticalmente à medida que novos itens são adicionados:
Lista horizontal
No XAML, um CollectionView
pode exibir seus itens em uma lista horizontal definindo sua ItemsLayout
propriedade como 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>
Como alternativa, esse layout também pode ser realizado definindo a ItemsLayout
propriedade como um LinearItemsLayout
objeto, especificando o membro de Horizontal
ItemsLayoutOrientation
enumeração como o valor da Orientation
propriedade:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Horizontal
};
Isso resulta em uma única lista de linhas, que cresce horizontalmente à medida que novos itens são adicionados:
Grade vertical
No XAML, um CollectionView
pode exibir seus itens em uma grade vertical definindo sua ItemsLayout
propriedade como 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>
Como alternativa, esse layout também pode ser realizado definindo a ItemsLayout
propriedade como um GridItemsLayout
objeto cuja Orientation
propriedade está definida como Vertical
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};
Por padrão, um vertical GridItemsLayout
exibirá itens em uma única coluna. No entanto, este exemplo define a GridItemsLayout.Span
propriedade como 2. Isso resulta em uma grade de duas colunas, que cresce verticalmente à medida que novos itens são adicionados:
Grade horizontal
No XAML, um CollectionView
pode exibir seus itens em uma grade horizontal definindo sua ItemsLayout
propriedade como 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>
Como alternativa, esse layout também pode ser realizado definindo a ItemsLayout
propriedade como um GridItemsLayout
objeto cuja Orientation
propriedade está definida como Horizontal
:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal"
Span="4" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};
Por padrão, um horizontal GridItemsLayout
exibirá itens em uma única linha. No entanto, este exemplo define a GridItemsLayout.Span
propriedade como 4. Isso resulta em uma grade de quatro linhas, que cresce horizontalmente à medida que novos itens são adicionados:
Cabeçalhos e rodapés
CollectionView
pode apresentar um cabeçalho e rodapé que rolam com os itens na lista. O cabeçalho e o rodapé podem ser cadeias de caracteres, exibições ou DataTemplate
objetos.
CollectionView
define as seguintes propriedades para especificar o cabeçalho e o rodapé:
Header
, do tipoobject
, especifica a cadeia de caracteres, a associação ou a exibição que será exibida no início da lista.HeaderTemplate
, do tipoDataTemplate
, especifica oDataTemplate
a ser usado para formatar oHeader
.Footer
, do tipoobject
, especifica a cadeia de caracteres, a associação ou a exibição que será exibida no final da lista.FooterTemplate
, do tipoDataTemplate
, especifica oDataTemplate
a ser usado para formatar oFooter
.
Essas propriedades são apoiadas por BindableProperty
objetos, o que significa que as propriedades podem ser destinos de associações de dados.
Quando um cabeçalho é adicionado a um layout que cresce horizontalmente, da esquerda para a direita, o cabeçalho é exibido à esquerda da lista. Da mesma forma, quando um rodapé é adicionado a um layout que cresce horizontalmente, da esquerda para a direita, o rodapé é exibido à direita da lista.
Exibir cadeias de caracteres no cabeçalho e no rodapé
As Header
propriedades e Footer
podem ser definidas string
como valores, conforme mostrado no exemplo a seguir:
<CollectionView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2019">
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
Header = "Monkeys",
Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Esse código resulta nas seguintes capturas de tela, com o cabeçalho mostrado na captura de tela do iOS e o rodapé mostrado na captura de tela do Android:
Exibir exibições no cabeçalho e rodapé
As Header
propriedades e Footer
podem ser definidas como uma exibição. Pode ser uma exibição única ou uma exibição que contém várias exibições filho. O exemplo a seguir mostra as Header
propriedades e Footer
cada um definido como um StackLayout
objeto que contém um Label
objeto :
<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>
Este é o código C# equivalente:
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");
Esse código resulta nas seguintes capturas de tela, com o cabeçalho mostrado na captura de tela do iOS e o rodapé mostrado na captura de tela do Android:
Exibir um cabeçalho e rodapé com modelo
As HeaderTemplate
propriedades e FooterTemplate
podem ser definidas como DataTemplate
objetos usados para formatar o cabeçalho e o rodapé. Nesse cenário, as Header
propriedades e Footer
devem ser associadas à origem atual para que os modelos sejam aplicados, conforme mostrado no exemplo a seguir:
<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>
Este é o código C# equivalente:
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");
Esse código resulta nas seguintes capturas de tela, com o cabeçalho mostrado na captura de tela do iOS e o rodapé mostrado na captura de tela do Android:
Espaçamento de item
Por padrão, não há espaço entre cada item em um CollectionView
. Esse comportamento pode ser alterado definindo as propriedades no layout de itens usado pelo CollectionView
.
Quando um CollectionView
define sua ItemsLayout
propriedade como um LinearItemsLayout
objeto , a LinearItemsLayout.ItemSpacing
propriedade pode ser definida como um double
valor que representa o espaço entre os itens:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Observação
A LinearItemsLayout.ItemSpacing
propriedade tem um conjunto de retorno de chamada de validação, que garante que o valor da propriedade seja sempre maior ou igual a 0.
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
{
ItemSpacing = 20
}
};
Esse código resulta em uma lista vertical de coluna única, que tem um espaçamento de 20 entre itens:
Quando um CollectionView
define sua ItemsLayout
propriedade como um GridItemsLayout
objeto , as GridItemsLayout.VerticalItemSpacing
propriedades e GridItemsLayout.HorizontalItemSpacing
podem ser definidas como double
valores que representam o espaço vazio vertical e horizontalmente entre os itens:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
VerticalItemSpacing="20"
HorizontalItemSpacing="30" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Observação
As GridItemsLayout.VerticalItemSpacing
propriedades e GridItemsLayout.HorizontalItemSpacing
têm retornos de chamada de validação definidos, que garantem que os valores das propriedades sejam sempre maiores ou iguais a 0.
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
{
VerticalItemSpacing = 20,
HorizontalItemSpacing = 30
}
};
Esse código resulta em uma grade vertical de duas colunas, que tem um espaçamento vertical de 20 entre itens e um espaçamento horizontal de 30 entre itens:
Dimensionamento de itens
Por padrão, cada item em um CollectionView
é medido e dimensionado individualmente, desde que os elementos da interface do DataTemplate
usuário no não especifiquem tamanhos fixos. Esse comportamento, que pode ser alterado, é especificado pelo valor da CollectionView.ItemSizingStrategy
propriedade. Esse valor de propriedade pode ser definido como um dos membros de ItemSizingStrategy
enumeração:
MeasureAllItems
– cada item é medido individualmente. Esse é o valor padrão.MeasureFirstItem
– somente o primeiro item é medido, com todos os itens subsequentes recebendo o mesmo tamanho que o primeiro item.
Importante
A MeasureFirstItem
estratégia de dimensionamento resultará em maior desempenho quando usado em situações em que o tamanho do item se destina a ser uniforme em todos os itens.
O exemplo de código a seguir mostra a configuração da ItemSizingStrategy
propriedade:
<CollectionView ...
ItemSizingStrategy="MeasureFirstItem">
...
</CollectionView>
Este é o código C# equivalente:
CollectionView collectionView = new CollectionView
{
...
ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};
Redimensionamento dinâmico de itens
Os itens em um CollectionView
podem ser redimensionados dinamicamente em runtime alterando as propriedades relacionadas ao layout dos elementos dentro do DataTemplate
. Por exemplo, o exemplo de código a seguir altera as HeightRequest
propriedades e WidthRequest
de um Image
objeto :
void OnImageTapped(object sender, EventArgs e)
{
Image image = sender as Image;
image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}
O OnImageTapped
manipulador de eventos é executado em resposta a um Image
objeto que está sendo tocado e altera as dimensões da imagem para que ela seja exibida com mais facilidade:
Layout da direita para a esquerda
CollectionView
pode layout de seu conteúdo em uma direção de fluxo da direita para a esquerda definindo sua FlowDirection
propriedade como RightToLeft
. No entanto, a FlowDirection
propriedade deve ser definida idealmente em uma página ou layout raiz, o que faz com que todos os elementos dentro da página, ou layout raiz, respondam à direção do fluxo:
<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>
O padrão FlowDirection
para um elemento com um pai é MatchParent
. Portanto, o herda o FlowDirection
valor da propriedade do StackLayout
, que, por sua vez, herda o FlowDirection
valor da propriedade do ContentPage
.CollectionView
Isso resulta no layout da direita para a esquerda mostrado nas seguintes capturas de tela:
Para obter mais informações sobre a direção do fluxo, consulte Localização da direita para a esquerda.