Partilhar via


Especificar layout CollectionView

Browse sample. Navegue pelo exemplo

A interface do usuário do aplicativo multiplataforma .NET (.NET MAUI) CollectionView define as seguintes propriedades que controlam o layout:

  • ItemsLayout, do tipo IItemsLayout, especifica o layout a ser usado.
  • ItemSizingStrategy, do tipo ItemSizingStrategy, 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 lista de coluna única que cresce verticalmente à medida que novos itens são adicionados.
  • Lista horizontal – uma lista de linha única 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 que deriva da ItemsLayout classe. Essa classe define as seguintes propriedades:

  • Orientation, do tipo ItemsLayoutOrientation, especifica a direção na qual o expande à medida que os CollectionView itens são adicionados.
  • SnapPointsAlignment, do tipo SnapPointsAlignment, especifica como os pontos de ajuste são alinhados com os itens.
  • SnapPointsType, do tipo SnapPointsType, especifica o comportamento dos pontos de ajuste durante a rolagem.

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 em Rolagem de controle em um CollectionView.

A enumeração ItemsLayoutOrientation define os seguintes membros:

  • Vertical indica que o se expandirá verticalmente à medida que os CollectionView itens forem adicionados.
  • Horizontal indica que o se expandirá horizontalmente à medida que os CollectionView itens forem adicionados.

A LinearItemsLayout classe herda da ItemsLayout classe e define uma ItemSpacing propriedade, do tipo double, que representa o espaço vazio ao redor 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 estática Vertical e Horizontal membros. Esses membros podem ser usados para criar listas verticais ou horizontais, respectivamente. Como alternativa, um objeto pode ser criado, especificando um membro de enumeração como um LinearItemsLayoutItemsLayoutOrientation argumento.

A GridItemsLayout classe herda da ItemsLayout classe e define as seguintes propriedades:

  • VerticalItemSpacing, do tipo double, que representa o espaço vazio vertical ao redor de cada item. O valor padrão dessa propriedade é 0 e seu valor sempre deve ser maior ou igual a 0.
  • HorizontalItemSpacing, do tipo double, que representa o espaço vazio horizontal ao redor de cada item. O valor padrão dessa propriedade é 0 e seu valor sempre deve ser maior ou igual a 0.
  • Span, do tipo int, 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 fins de completude, em XAML a 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 enumeração como o VerticalItemsLayoutOrientation 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 lista de coluna única, que cresce verticalmente à medida que novos itens são adicionados:

Screenshot of CollectionView vertical list layout.

Dica

Colocar um dentro de um CollectionViewVerticalStackLayout pode parar a CollectionView rolagem e pode limitar o número de itens que são exibidos. Nessa situação, substitua o VerticalStackLayout por um Gridarquivo .

Lista horizontal

Em 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 enumeração como o HorizontalItemsLayoutOrientation 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 lista de linhas únicas, que cresce horizontalmente à medida que novos itens são adicionados:

Screenshot of CollectionView horizontal list layout.

Grade vertical

Em 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 é 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, uma 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:

Screenshot of CollectionView vertical grid layout.

Grade horizontal

Em 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 é 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:

Screenshot of CollectionView horizontal grid layout.

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, modos de exibição ou DataTemplate objetos.

CollectionView define as seguintes propriedades para especificar o cabeçalho e o rodapé:

  • Header, do tipo object, especifica a cadeia de caracteres, associação ou modo de exibição que será exibido no início da lista.
  • HeaderTemplate, do tipo DataTemplate, especifica o a ser usado para formatar o DataTemplateHeader.
  • Footer, do tipo object, especifica a cadeia de caracteres, associação ou modo de exibição que será exibido no final da lista.
  • FooterTemplate, do tipo DataTemplate, especifica o a ser usado para formatar o DataTemplateFooter.

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.

As Header propriedades e Footer podem ser definidas como string 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:

Screenshot of a CollectionView string header and footer.

As Header propriedades e Footer podem ser definidas como uma exibição. Pode ser um único modo de exibição ou um modo de exibição que contenha vários modos de exibição filho. O exemplo a seguir mostra as Header propriedades e Footer cada conjunto para um objeto que contém um StackLayoutLabel objeto:

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

Este é o código C# equivalente:

StackLayout headerStackLayout = new StackLayout();
header.StackLayout.Add(new Label { Text = "Monkeys", ... } );
StackLayout footerStackLayout = new StackLayout();
footerStackLayout.Add(new Label { Text = "Friends of Xamarin Monkey", ... } );

CollectionView collectionView = new CollectionView
{  
    Header = headerStackLayout,
    Footer = footerStackLayout            
};
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:

Screenshot of CollectionView header and footer using views.

As HeaderTemplate propriedades e podem ser definidas como DataTemplate objetos que são usados para formatar o cabeçalho e FooterTemplate o rodapé. Nesse cenário, as Header propriedades e Footer devem se vincular à fonte 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="12"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.HeaderTemplate>
    <CollectionView.FooterTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Friends of Xamarin Monkey"
                       FontSize="12"
                       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:

Screenshot of a CollectionView header and footer using templates.

Espaçamento entre itens

Por padrão, não há espaço entre cada item em um CollectionViewarquivo . Esse comportamento pode ser alterado definindo propriedades no layout de itens usado pelo CollectionView.

Quando um define sua ItemsLayout propriedade como um objeto, a LinearItemsLayout.ItemSpacing propriedade pode ser definida como um doubleCollectionViewLinearItemsLayout valor que representa o espaço entre 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:

Screenshot of CollectionView with item spacing.

Quando um define sua ItemsLayout propriedade como um GridItemsLayoutCollectionView objeto, as GridItemsLayout.VerticalItemSpacing propriedades e podem ser definidas como double valores que representam o espaço vazio vertical e GridItemsLayout.HorizontalItemSpacing 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, o que garante 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:

Screenshot of a CollectionView with grid item spacing.

Dimensionamento de itens

Por padrão, cada item em um CollectionView é medido e dimensionado individualmente, desde que os elementos da interface do usuário no DataTemplate 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 ItemSizingStrategy membros de enumeração:

  • MeasureAllItems – cada item é medido individualmente. Esse é o valor padrão.
  • MeasureFirstItem – apenas 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 usada em situações em que o tamanho do item deve 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 tempo de execução alterando as propriedades relacionadas ao layout dos elementos dentro do DataTemplate. Por exemplo, o exemplo de código a seguir altera as propriedades e WidthRequest de HeightRequest 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 visualizada mais facilmente:

Screenshot of a CollectionView with dynamic item sizing.

Layout da direita para a esquerda

CollectionView pode esquematizar 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 idealmente ser definida 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://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CollectionViewDemos.Views.VerticalListFlowDirectionPage"
             Title="Vertical list (RTL FlowDirection)"
             FlowDirection="RightToLeft">
    <Grid Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}">
            ...
        </CollectionView>
    </Grid>
</ContentPage>

O padrão FlowDirection para um elemento com um pai é MatchParent. Portanto, o herda o valor da propriedade do , que, por sua vez, herda o CollectionViewFlowDirectionFlowDirection valor da propriedade do .StackLayoutContentPage Isso resulta no layout da direita para a esquerda mostrado na captura de tela a seguir:

Screenshot of a CollectionView right-to-left vertical list layout.

Para obter mais informações sobre a direção do fluxo, consulte Localização da direita para a esquerda.