Xamarin.Forms Agrupamento CollectionView

Baixar exemplo Baixar o exemplo

Conjuntos de dados grandes geralmente podem se tornar difíceis 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 dos 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 BindableProperty objetos , o que significa que as propriedades podem ser destinos de associações de dados.

As capturas de tela a seguir mostram uma CollectionView exibição de 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 que possam ser exibidos. Isso pode ser feito criando uma lista de grupos, em que cada grupo é uma lista de itens. A lista de grupos deve ser uma coleção IEnumerable<T> , em T que define duas partes de dados:

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

O processo de agrupamento de 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> , em T que é 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 à IEnumerable<T> coleção.

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 Animal classe modela um único item. Um tipo que modela um grupo de itens pode 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 AnimalGroup classe herda da List<T> classe e adiciona uma Name propriedade que representa o nome do grupo.

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

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

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

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

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 Animals coleção. O primeiro AnimalGroup é chamado Bearse contém uma List<Animal> coleção de detalhes de urso. O segundo AnimalGroup é chamado Monkeyse contém uma List<Animal> coleção de detalhes do macaco.

Exibir dados agrupados

CollectionView exibirá dados agrupados, desde que os dados foram agrupados corretamente, definindo a IsGrouped propriedade truecomo :

<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, consulte Definir a aparência do item.

Observação

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

Personalizar o cabeçalho do grupo

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

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

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

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

A aparência de cada rodapé de grupo pode ser personalizada definindo a CollectionView.GroupFooterTemplate propriedade como um 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, em iOS e Android

Grupos vazios

Quando um 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, cabeçalhos de grupo e rodapés para grupos vazios podem ser exibidos na parte superior do CollectionView.

Agrupar sem modelos

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

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

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