Partilhar via


Xamarin.Forms Agrupamento CollectionView

Grandes conjuntos de dados muitas vezes podem se tornar complicados quando apresentados em uma lista de rolagem contínua. Nesse cenário, organizar os dados em grupos pode melhorar a experiência do usuário, facilitando a navegação nos dados.

CollectionView Dá suporte à exibição de dados agrupados e define as seguintes propriedades que controlam como eles serão apresentados:

  • IsGrouped, do tipo bool, indica se os dados subjacentes devem ser exibidos em grupos. O valor padrão dessa propriedade é false.
  • GroupHeaderTemplate, do tipo DataTemplate, o modelo a ser usado para o cabeçalho de cada grupo.
  • GroupFooterTemplate, do tipo DataTemplate, o modelo a ser usado para o rodapé de cada grupo.

Essas propriedades são apoiadas por objetos BindableProperty, o que significa que as propriedades podem ser alvos de vinculações de dados.

As capturas de tela a seguir mostram a exibição de CollectionView dados agrupados:

Captura de tela de dados agrupados em um CollectionView, no iOS e no Android

Para obter mais informações sobre modelos de dados, consulte Xamarin.Forms Modelos de dados.

Agrupar dados

Os dados devem ser agrupados antes de serem exibidos. Isso pode ser feito criando uma lista de grupos, onde cada grupo é uma lista de itens. A lista de grupos deve ser uma coleção IEnumerable<T>, onde T define dois dados:

  • Um nome de grupo.
  • Uma coleção IEnumerable que define os itens pertencentes ao grupo.

O processo para agrupar dados, portanto, é:

  • Crie um tipo que modele um único item.
  • Crie um tipo que modele um único grupo de itens.
  • Crie uma coleção IEnumerable<T>, onde T é o tipo que modela um único grupo de itens. Essa coleção é, portanto, uma coleção de grupos, que armazena os dados agrupados.
  • Adicione dados à coleção IEnumerable<T>.

Exemplo

Ao agrupar dados, a primeira etapa é criar um tipo que modele um único item. O exemplo a seguir mostra a Animal classe do aplicativo de exemplo:

public class Animal
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

A classe Animal modela um único item. Um tipo que modela um grupo de itens pode então ser criado. O exemplo a seguir mostra a AnimalGroup classe do aplicativo de exemplo:

public class AnimalGroup : List<Animal>
{
    public string Name { get; private set; }

    public AnimalGroup(string name, List<Animal> animals) : base(animals)
    {
        Name = name;
    }
}

A classe AnimalGroup herda da classe List<T> e adiciona uma propriedade Name que representa o nome do grupo.

Uma IEnumerable<T> coleção de grupos pode então ser criada:

public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

Esse código define uma coleção chamada Animals, onde cada item da coleção é um objeto AnimalGroup. Cada objeto AnimalGroup compreende um nome e uma coleção List<Animal> que define os objetos Animal no grupo.

Os dados agrupados podem então ser adicionados à coleção Animals:

Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
    new Animal
    {
        Name = "American Black Bear",
        Location = "North America",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
    },
    new Animal
    {
        Name = "Asian Black Bear",
        Location = "Asia",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
    },
    // ...
}));

Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
    new Animal
    {
        Name = "Baboon",
        Location = "Africa & Asia",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
    },
    new Animal
    {
        Name = "Capuchin Monkey",
        Location = "Central & South America",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
    },
    new Animal
    {
        Name = "Blue Monkey",
        Location = "Central and East Africa",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
    },
    // ...
}));

Esse código cria dois grupos na coleção Animals. O primeiro AnimalGroup é nomeado Bears e contém uma List<Animal> coleção de detalhes do urso. O segundo AnimalGroup é denominado Monkeys e contém uma List<Animal> coleção de detalhes do macaco.

Exibir dados agrupados

CollectionView exibirá dados agrupados, desde que os dados tenham sido agrupados corretamente, definindo a propriedade IsGrouped como true:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                ...
                <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>

Este é o código C# equivalente:

CollectionView collectionView = new CollectionView
{
    IsGrouped = true
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...

A aparência de cada item no CollectionView é definida definindo a CollectionView.ItemTemplate propriedade como um DataTemplate. Para obter mais informações, veja Definir a aparência do item.

Observação

Por padrão, CollectionView exibirá o nome do grupo no cabeçalho e rodapé do grupo. Esse comportamento pode ser alterado personalizando o cabeçalho e o rodapé do grupo.

Personalize o cabeçalho do grupo

A aparência de cada cabeçalho de grupo pode ser personalizada definindo a propriedade CollectionView.GroupHeaderTemplate como um DataTemplate:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate>
            <Label Text="{Binding Name}"
                   BackgroundColor="LightGray"
                   FontSize="Large"
                   FontAttributes="Bold" />
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
</CollectionView>

Nesse exemplo, cada cabeçalho de grupo é definido como um Label que exibe o nome do grupo e possui outras propriedades de aparência definidas. As capturas de tela a seguir mostram o cabeçalho do grupo personalizado:

Captura de tela de um cabeçalho de grupo personalizado em um CollectionView, no iOS e no Android

A aparência de cada rodapé de grupo pode ser personalizada definindo a CollectionView.GroupFooterTemplate propriedade como :DataTemplate

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupFooterTemplate>
        <DataTemplate>
            <Label Text="{Binding Count, StringFormat='Total animals: {0:D}'}"
                   Margin="0,0,0,10" />
        </DataTemplate>
    </CollectionView.GroupFooterTemplate>
</CollectionView>

Neste exemplo, cada rodapé de grupo é definido como um Label que exibe o número de itens no grupo. As capturas de tela a seguir mostram o rodapé do grupo personalizado:

Captura de tela de um rodapé de grupo personalizado em um CollectionView, no iOS e no Android

Grupos vazios

Quando a CollectionView exibe dados agrupados, ele exibe todos os grupos que estão vazios. Esses grupos serão exibidos com um cabeçalho e rodapé de grupo, indicando que o grupo está vazio. As capturas de tela a seguir mostram um grupo vazio:

Captura de tela de um grupo vazio em um CollectionView, no iOS e no Android

Observação

No iOS 10 e inferior, os cabeçalhos e rodapés de grupos vazios podem ser exibidos na parte superior do CollectionView.

Grupo sem modelos

CollectionView pode exibir dados agrupados corretamente sem definir a propriedade CollectionView.ItemTemplate como um DataTemplate:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true" />

Nesse cenário, dados significativos podem ser exibidos substituindo o método ToString no tipo que modela um único item e no tipo que modela um único grupo de itens.