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 tipobool
, indica se os dados subjacentes devem ser exibidos em grupos. O valor padrão dessa propriedade éfalse
.GroupHeaderTemplate
, do tipoDataTemplate
, o modelo a ser usado para o cabeçalho de cada grupo.GroupFooterTemplate
, do tipoDataTemplate
, 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:
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>
, ondeT
é 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:
Personalizar o rodapé do grupo
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:
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:
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.