ListView

Browse sample. Navegue pelo exemplo

A interface do usuário do aplicativo multiplataforma .NET (.NET MAUI) ListView exibe uma lista vertical rolável de itens de dados selecionáveis. Enquanto ListView gerencia a aparência da lista, a aparência de cada item na lista é definida por um que usa um DataTemplateCell para exibir itens. O .NET MAUI inclui tipos de célula para exibir combinações de texto e imagens, e você também pode definir células personalizadas que exibem qualquer conteúdo desejado. ListView também inclui suporte para exibir cabeçalhos e rodapés, dados agrupados, pull-to-refresh e itens de menu de contexto.

A ListView classe deriva da classe, da ItemsView<Cell> qual herda as seguintes propriedades:

  • ItemsSource, do tipo IEnumerable, especifica a coleção de itens a serem exibidos e tem um valor padrão de null.
  • ItemTemplate, do tipo DataTemplate, especifica o modelo a ser aplicado a cada item na coleção de itens a serem exibidos.

ListView define as propriedades a seguir:

  • Footer, do tipo object, especifica a cadeia de caracteres ou exibição que será exibida no final da lista.
  • FooterTemplate, do tipo DataTemplate, especifica o a ser usado para formatar o DataTemplateFooter.
  • GroupHeaderTemplate, do tipo DataTemplate, define o DataTemplate usado para definir a aparência do cabeçalho de cada grupo. Esta propriedade é mutuamente exclusiva com a GroupDisplayBinding propriedade. Portanto, definir essa propriedade será definido GroupDisplayBinding como null.
  • HasUnevenRows, do tipo bool, indica se os itens na lista podem ter linhas de alturas diferentes. O valor padrão dessa propriedade é false.
  • Header, do tipo object, especifica a cadeia de caracteres ou exibição que será exibida no início da lista.
  • HeaderTemplate, do tipo DataTemplate, especifica o a ser usado para formatar o DataTemplateHeader.
  • HorizontalScrollBarVisibility, do tipo ScrollBarVisibility, indica quando a barra de rolagem horizontal ficará visível.
  • IsGroupedEnabled, do tipo bool, indica se os dados subjacentes devem ser exibidos em grupos. O valor padrão dessa propriedade é false.
  • IsPullToRefreshEnabled, do tipo bool, indica se o usuário pode passar o dedo para baixo para fazer com que o ListView atualize seus dados. O valor padrão dessa propriedade é false.
  • IsRefreshing, do tipo bool, indica se o ListView está atualizando no momento. O valor padrão dessa propriedade é false.
  • RefreshCommand, do tipo ICommand, representa o comando que será executado quando uma atualização for acionada.
  • RefreshControlColor, do tipo Color, determina a cor da visualização de atualização mostrada enquanto ocorre uma atualização.
  • RowHeight, do tipo int, determina a altura de cada linha quando HasUnevenRows é false.
  • SelectedItem, do tipo object, representa o item atualmente selecionado no ListView.
  • SelectionMode, do tipo ListViewSelectionMode, indica se os ListView itens podem ser selecionados no ou não. O valor padrão dessa propriedade é Single.
  • SeparatorColor, do tipo Color, define a cor da barra que separa os itens na lista.
  • SeparatorVisibility, do tipo SeparatorVisibility, define se os separadores são visíveis entre os itens.
  • VerticalScrollBarVisibility, do tipo ScrollBarVisibility, indica quando a barra de rolagem vertical estará visível.

Todas essas propriedades são apoiadas por BindableProperty objetos, o que significa que elas podem ser alvos de associações de dados e estilizadas.

Além disso, ListView define as seguintes propriedades que não são suportadas por BindableProperty objetos:

  • GroupDisplayBinding, do tipo BindingBase, a associação a ser usada para exibir o cabeçalho do grupo. Esta propriedade é mutuamente exclusiva com a GroupHeaderTemplate propriedade. Portanto, definir essa propriedade será definido GroupHeaderTemplate como null.
  • GroupShortNameBinding, do tipo BindingBase, a associação para o nome a ser exibido em listas de atalhos agrupadas.
  • CachingStrategy, do tipo ListViewCachingStrategy, define a estratégia de reutilização celular do ListView. Trata-se de uma propriedade somente leitura.

ListView define os seguintes eventos:

  • ItemAppearing, que é gerado quando a representação visual de um item está sendo adicionada ao layout visual do ListView. O ItemVisibilityEventArgs objeto que acompanha esse evento define Item e Index propriedades.
  • ItemDisappearing, que é gerado quando a representação visual de um item está sendo removida do layout visual do ListView. O ItemVisibilityEventArgs objeto que acompanha esse evento define Item e Index propriedades.
  • ItemSelected, que é gerado quando um novo item na lista é selecionado. O SelectedItemChangedEventArgs objeto que acompanha esse evento define SelectedItem e SelectedItemIndex propriedades.
  • ItemTapped, que é gerado quando um item no ListView é tocado. O ItemTappedEventArgs objeto que acompanha esse evento define Group, Iteme ItemIndex propriedades.
  • Refreshing, que é gerado quando uma operação pull to refresh é acionada ListViewno .
  • Scrolled, . O ScrolledEventArgs objeto que acompanha esse evento define ScrollX e ScrollY propriedades.
  • ScrollToRequested . O ScrollToRequestedEventArgs objeto que acompanha esse evento define Element, , , , ScrollXScrollYModePositione ShouldAnimate propriedades.

Preencher um ListView com dados

A ListView é preenchido com dados definindo sua ItemsSource propriedade para qualquer coleção que implementa IEnumerableo .

Importante

Se for necessário atualizar à medida que os ListView itens são adicionados, removidos ou alterados na coleção subjacente, a coleção subjacente deve ser uma IEnumerable coleção que envia notificações de alteração de propriedade, como ObservableCollection.

ListView pode ser preenchido com dados usando a vinculação de dados para vincular sua ItemsSource propriedade a uma IEnumerable coleção. Em XAML, isso é obtido com a Binding extensão de marcação:

<ListView ItemsSource="{Binding Monkeys}" />

Este é o código C# equivalente:

ListView listView = new ListView();
listView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Neste exemplo, os ItemsSource dados da propriedade se vinculam à Monkeys propriedade do modelo de exibição conectado.

Observação

As associações compiladas podem ser habilitadas para melhorar o desempenho da vinculação de dados em aplicativos .NET MAUI. Para obter mais informações, consulte Associações compiladas.

Para obter mais informações sobre vinculação de dados, consulte Vinculação de dados.

Definir a aparência do item

A aparência de cada item no ListView pode ser definida definindo a ItemTemplate propriedade como um DataTemplate:

<ListView ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <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>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Os elementos especificados no DataTemplate definem a aparência de cada item na lista, e o filho do DataTemplate deve ser um Cell objeto. No exemplo, o layout dentro do DataTemplate é gerenciado por um Gridarquivo . O Grid contém um Image objeto e dois Label objetos que se ligam às propriedades da Monkey classe:

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

A captura de tela a seguir mostra o resultado da modelagem de cada item na lista:

Screenshot of ListView where each item is templated.

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

Cells

A aparência de cada item em um é definida por um ListViewDataTemplate, e o DataTemplate deve fazer referência a uma Cell classe para exibir itens. Cada célula representa um item de dados no ListView. O .NET MAUI inclui as seguintes células internas:

  • TextCell, que exibe texto primário e secundário em linhas separadas.
  • ImageCell, que exibe uma imagem com texto primário e secundário em linhas separadas.
  • SwitchCell, que exibe texto e um interruptor que pode ser ligado ou desligado.
  • EntryCell, que exibe um rótulo e um texto editáveis.
  • ViewCell, que é uma célula personalizada cuja aparência é definida por um Viewarquivo . Esse tipo de célula deve ser usado quando você deseja definir completamente a aparência de cada item em um ListViewarquivo .

Normalmente, SwitchCell e EntryCell só será usado em um e não será usado em um TableViewListViewarquivo . Para obter mais informações sobre SwitchCell e , consulte TableViewEntryCell.

Célula de texto

A TextCell exibe texto primário e secundário em linhas separadas. TextCell define as propriedades a seguir:

  • Text, do tipo string, define o texto primário a ser exibido.
  • TextColor, do tipo Color, representa a cor do texto primário.
  • Detail, do tipo string, define o texto secundário a ser exibido.
  • DetailColor, do tipo Color, indica a cor do texto secundário.
  • Command, do tipo ICommand, define o comando que é executado quando a célula é tocada.
  • CommandParameter, do tipo object, representa o parâmetro que é passado para o comando.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que elas podem ser alvos de associações de dados e estilizadas.

O exemplo a seguir mostra o uso de um para definir a aparência de itens em um TextCellListView:

<ListView ItemsSource="{Binding Food}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextCell Text="{Binding Name}"
                      Detail="{Binding Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

A captura de tela a seguir mostra a aparência da célula resultante:

Screenshot of ListView where each item is a TextCell.

Célula de imagem

Um ImageCell exibe uma imagem com texto primário e secundário em linhas separadas. ImageCellHerda as propriedades de TextCelle define a propriedade, do tipo ImageSource, que especifica a imagem a ImageSource ser exibida na célula. Essa propriedade é apoiada por um BindableProperty objeto, o que significa que ele pode ser o destino de associações de dados e ser estilizado.

O exemplo a seguir mostra o uso de um para definir a aparência de itens em um ImageCellListView:

<ListView ItemsSource="{Binding Food}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ImageCell ImageSource="{Binding Image}"
                       Text="{Binding Name}"
                       Detail="{Binding Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

A captura de tela a seguir mostra a aparência da célula resultante:

Screenshot of ListView where each item is an ImageCell.

Exibir célula

A ViewCell é uma célula personalizada cuja aparência é definida por um Viewarquivo . ViewCell Define uma View propriedade, do tipo View, que define o modo de exibição que representa o conteúdo da célula. Essa propriedade é apoiada por um BindableProperty objeto, o que significa que ele pode ser o destino de associações de dados e ser estilizado.

Observação

A View propriedade é a propriedade content da ViewCell classe e, portanto, não precisa ser definida explicitamente a partir de XAML.

O exemplo a seguir mostra o uso de um para definir a aparência de itens em um ViewCellListView:

<ListView ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <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>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Dentro do , o layout pode ser gerenciado por qualquer layout do ViewCell.NET MAUI. Neste exemplo, o layout é gerenciado por um Gridarquivo . O Grid contém um Image objeto e dois Label objetos que se ligam às propriedades da Monkey classe.

A captura de tela a seguir mostra o resultado da modelagem de cada item na lista:

Screenshot of ListView where each item is templated with a ViewCell.

Escolher a aparência do item em tempo de execução

A aparência de cada item no pode ser escolhida em tempo de execução, com base no ListView valor do item, definindo a ItemTemplate propriedade como um DataTemplateSelector objeto:

<ContentPage ...
             xmlns:templates="clr-namespace:ListViewDemos.Templates">
    <ContentPage.Resources>
        <DataTemplate x:Key="AmericanMonkeyTemplate">
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>

        <DataTemplate x:Key="OtherMonkeyTemplate">
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>

        <templates:MonkeyDataTemplateSelector x:Key="MonkeySelector"
                                             AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
                                             OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <ListView ItemsSource="{Binding Monkeys}"
                  ItemTemplate="{StaticResource MonkeySelector}" />
    </StackLayout>
</ContentPage>

A ItemTemplate propriedade é definida como um MonkeyDataTemplateSelector objeto. O exemplo a seguir mostra a classe MonkeyDataTemplateSelector:

public class MonkeyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate AmericanMonkey { get; set; }
    public DataTemplate OtherMonkey { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
    }
}

A MonkeyDataTemplateSelector classe define AmericanMonkey e OtherMonkeyDataTemplate propriedades que são definidas para modelos de dados diferentes. A OnSelectTemplate substituição retorna o modelo, que exibe o nome e a localização do macaco em teal, quando o AmericanMonkey nome do macaco contém "América". Quando o nome do macaco não contém "América", a OnSelectTemplate substituição retorna o modelo, que exibe o nome e o OtherMonkey local do macaco em prata:

Screenshot of ListView runtime item template selection.

Para obter mais informações sobre seletores de modelo de dados, consulte Criar um DataTemplateSelector.

Responder à seleção do item

Por padrão, ListView a seleção está habilitada. No entanto, esse comportamento pode ser alterado definindo a SelectionMode propriedade. A enumeração ListViewSelectionMode define os seguintes membros:

  • None – indica que os itens não podem ser selecionados.
  • Single – indica que um único item pode ser selecionado, com o item selecionado sendo destacado. Esse é o valor padrão.

ListView Define um evento que é gerado quando a propriedade é alterada, devido ao usuário selecionar um item da lista ou quando um ItemSelected aplicativo define a SelectedItem propriedade. O SelectedItemChangedEventArgs objeto que acompanha esse evento tem SelectedItem e SelectedItemIndex propriedades.

Quando a SelectionMode propriedade é definida como Single, um único item no ListView pode ser selecionado. Quando um item é selecionado, a SelectedItem propriedade será definida como o valor do item selecionado. Quando essa propriedade é alterada, o ItemSelected evento é gerado.

O exemplo a seguir mostra um que pode responder à seleção de ListView item único:

<ListView ItemsSource="{Binding Monkeys}"
          ItemSelected="OnItemSelected">
    ...
</ListView>

Neste exemplo, o manipulador de eventos é executado quando o evento é acionado, com o manipulador de eventos recuperando o OnItemSelectedItemSelected item selecionado:

void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
    Monkey item = args.SelectedItem as Monkey;
}

A captura de tela a seguir mostra a seleção de item único em um ListView:

Screenshot of a ListView with a selection.

Desmarcar a seleção

A SelectedItem propriedade pode ser limpa definindo-a, ou o objeto ao qual ela se vincula, como null.

Desativar seleção

ListView A seleção está habilitada por padrão. No entanto, ele pode ser desabilitado definindo a SelectionMode propriedade como None:

<ListView ...
          SelectionMode="None" />

Quando a propriedade é definida como None, os itens no ListView não podem ser selecionados, a SelectionModeSelectedItem propriedade permanecerá nulle o ItemSelected evento não será disparado.

Dados de cache

ListView é uma exibição poderosa para exibir dados, mas tem algumas limitações. O desempenho da rolagem pode ser prejudicado ao usar células personalizadas, especialmente quando elas contêm hierarquias de exibição profundamente aninhadas ou usam determinados layouts que exigem medições complexas. Felizmente, existem técnicas que você pode usar para evitar o mau desempenho.

A ListView é frequentemente usado para exibir muito mais dados do que cabe na tela. Por exemplo, um aplicativo de música pode ter uma biblioteca de músicas com milhares de entradas. Criar um item para cada entrada desperdiçaria memória valiosa e teria um desempenho ruim. Criar e destruir linhas constantemente exigiria que o aplicativo instanciasse e limpasse objetos constantemente, o que também teria um desempenho ruim.

Para conservar memória, os equivalentes nativos ListView de cada plataforma têm recursos internos para reutilizar linhas. Somente as células visíveis na tela são carregadas na memória e o conteúdo é carregado nas células existentes. Esse padrão impede que o aplicativo instancie milhares de objetos, economizando tempo e memória.

O .NET MAUI permite a reutilização de ListView células por meio da ListViewCachingStrategy enumeração, que define os seguintes membros:

  • RetainElement, especifica que o ListView gerará uma célula para cada item na lista.
  • RecycleElement, especifica que o tentará minimizar o volume de memória e a velocidade de execução reciclando as células da ListView lista.
  • RecycleElementAndDataTemplate, ao RecycleElement mesmo tempo em que garante que, quando um usa um ListViewDataTemplateSelector, DataTemplate os objetos são armazenados em cache pelo tipo de item na lista.

Reter elementos

A RetainElement estratégia de cache especifica que o ListView gerará uma célula para cada item na lista e é o comportamento padrão ListView . Deve ser utilizado nas seguintes circunstâncias:

  • Cada célula tem um grande número de ligações (20-30+).
  • O modelo de célula é alterado com frequência.
  • O teste revela que a RecycleElement estratégia de cache resulta em uma velocidade de execução reduzida.

É importante reconhecer as consequências da estratégia de RetainElement cache ao trabalhar com células personalizadas. Qualquer código de inicialização de célula precisará ser executado para cada criação de célula, que pode ser várias vezes por segundo. Nessa circunstância, técnicas de layout que eram boas em uma página, como o uso de vários objetos aninhados StackLayout , tornam-se gargalos de desempenho quando são configuradas e destruídas em tempo real à medida que o usuário rola.

Reciclar elementos

A RecycleElement estratégia de cache especifica que o tentará minimizar o volume de memória e a velocidade de execução reciclando as células da ListView lista. Esse modo nem sempre oferece uma melhoria de desempenho, e os testes devem ser realizados para determinar quaisquer melhorias. No entanto, é a escolha preferida e deve ser usada nas seguintes circunstâncias:

  • Cada célula tem um número pequeno a moderado de ligações.
  • Cada célula define BindingContext todos os dados da célula.
  • Cada célula é em grande parte semelhante, com o modelo de célula imutável.

Durante a virtualização, a célula terá seu contexto de vinculação atualizado e, portanto, se um aplicativo usar esse modo, ele deverá garantir que as atualizações de contexto de vinculação sejam tratadas adequadamente. Todos os dados sobre a célula devem vir do contexto de vinculação ou erros de consistência podem ocorrer. Esse problema pode ser evitado usando a vinculação de dados para exibir dados de célula. Como alternativa, os OnBindingContextChanged dados da célula devem ser definidos na substituição, em vez de no construtor da célula personalizada, como mostrado no exemplo a seguir:

public class CustomCell : ViewCell
{
    Image image = null;

    public CustomCell()
    {
        image = new Image();
        View = image;
    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();

        var item = BindingContext as ImageItem;
        if (item != null)
        {
            image.Source = item.ImageUrl;
        }
    }
}

Reciclar elementos com um DataTemplateSelector

Quando um usa um para selecionar um DataTemplateListViewDataTemplateSelector , a estratégia de cache não armazena RecycleElement objetos em cache.DataTemplate Em vez disso, um DataTemplate é selecionado para cada item de dados na lista.

Observação

A RecycleElement estratégia de cache requer que, quando um é solicitado a selecionar um, cada DataTemplate um DataTemplateSelectorDataTemplate deve retornar o mesmo ViewCell tipo. Por exemplo, dado um com um que pode retornar (MyDataTemplateAonde retorna um do tipo ), ou (onde MyDataTemplateBMyDataTemplateA retorna um ViewCellDataTemplateSelectorListViewViewCell do tipo MyViewCellBMyViewCellA), quando MyDataTemplateA é retornado ele deve retornar MyViewCellA ou MyDataTemplateB uma exceção será lançada.

Reciclar elementos com DataTemplates

A RecycleElementAndDataTemplate estratégia de cache baseia-se na estratégia de cache, garantindo adicionalmente que, quando um usa um para selecionar um DataTemplateListViewDataTemplateSelector , RecycleElementDataTemplate os objetos são armazenados em cache pelo tipo de item na lista. Portanto, os objetos são selecionados uma vez por tipo de item, DataTemplate em vez de uma vez por instância de item.

Observação

A RecycleElementAndDataTemplate estratégia de cache requer que os objetos retornados DataTemplateSelector pelo deve usar o DataTemplate construtor que DataTemplate usa um Typearquivo .

Definir a estratégia de cache

A ListView estratégia de cache pode ser definida por em XAML definindo o CachingStrategy atributo:

<ListView CachingStrategy="RecycleElement">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
              ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

No C#, a estratégia de cache é definida por meio de uma sobrecarga do construtor:

ListView listView = new ListView(ListViewCachingStrategy.RecycleElement);

Definir a estratégia de cache em um ListView subclassificado

Definir o atributo de XAML em uma subclasse ListView não produzirá o CachingStrategy comportamento desejado, porque não há nenhuma CachingStrategy propriedade em ListView. A solução para esse problema é especificar um construtor no subclassed ListView que aceita um ListViewCachingStrategy parâmetro e o passa para a classe base:

public class CustomListView : ListView
{
    public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
    {
    }
    ...
}

Em seguida, o valor de enumeração pode ser especificado a partir de XAML usando o ListViewCachingStrategyx:Arguments atributo:

<local:CustomListView>
    <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
    </x:Arguments>
</local:CustomListView>

Cabeçalhos e rodapés

ListView 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.

ListView 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.

As Header propriedades e Footer podem ser definidas como string valores, conforme mostrado no exemplo a seguir:

<ListView ItemsSource="{Binding Monkeys}"
          Header="Monkeys"
          Footer="2022">
    ...
</ListView>

A captura de tela a seguir mostra o cabeçalho resultante:

Screenshot of a ListView string header.

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:

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

A captura de tela a seguir mostra o cabeçalho resultante:

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:

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

Separadores de itens de controle

Por padrão, os separadores são exibidos entre ListView itens no iOS e no Android. Esse comportamento pode ser alterado definindo a SeparatorVisibility propriedade, do tipo SeparatorVisibility, como None:

<ListView ...
          SeparatorVisibility="None" />

Além disso, quando o separador está habilitado, sua cor pode ser definida com a SeparatorColor propriedade:

<ListView ...
          SeparatorColor="Blue" />

Itens de tamanho

Por padrão, todos os itens em um ListView têm a mesma altura, que é derivada do conteúdo do que define a DataTemplate aparência de cada item. No entanto, esse comportamento pode ser alterado com as HasUnevenRows propriedades e RowHeight . Por padrão, a HasUnevenRows propriedade é false.

A RowHeight propriedade pode ser definida como um int que representa a altura de cada item no ListView, desde que HasUnevenRows seja false. Quando HasUnevenRows é definido como true, cada item no ListView pode ter uma altura diferente. A altura de cada item será derivada do conteúdo do item e, portanto, cada item DataTemplateserá dimensionado para o seu conteúdo.

Itens individuais ListView podem ser programaticamente redimensionados em tempo de execução alterando as propriedades relacionadas ao layout de elementos dentro do DataTemplate, desde que a HasUnevenRows propriedade seja true. O exemplo a seguir altera a altura de um Image objeto quando ele é tocado:

void OnImageTapped(object sender, EventArgs args)
{
    Image image = sender as Image;
    ViewCell viewCell = image.Parent.Parent as ViewCell;

    if (image.HeightRequest < 250)
    {
      image.HeightRequest = image.Height + 100;
      viewCell.ForceUpdateSize();
    }
}

Neste exemplo, o OnImageTapped manipulador de eventos é executado em resposta a um Image objeto que está sendo tocado. O manipulador de eventos atualiza a altura do Image e o método atualiza o Cell.ForceUpdateSize tamanho da célula, mesmo quando ela não está visível no momento.

Aviso

O uso excessivo do dimensionamento dinâmico de itens pode causar ListView degradação no desempenho.

Layout da direita para a esquerda

ListView 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="ListViewDemos.RightToLeftListPage"
             Title="Right to left list"
             FlowDirection="RightToLeft">
    <StackLayout Margin="20">
        <ListView ItemsSource="{Binding Monkeys}">
            ...
        </ListView>
    </StackLayout>
</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 ListViewFlowDirectionFlowDirection valor da propriedade do .StackLayoutContentPage

Exibir dados agrupados

Conjuntos de dados grandes muitas vezes podem se tornar pesados 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 pelos dados.

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

  • Um nome de grupo.
  • Uma IEnumerable coleção 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 IEnumerable<T> coleção, onde T é o tipo que modela um único grupo de itens. Essa coleção é 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 classe Animal:

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 classe AnimalGroup:

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 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 na coleção é um AnimalGroup objeto. Cada AnimalGroup objeto compreende um nome e uma List<Animal> coleção que define os Animal objetos no grupo.

Os dados agrupados podem então 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 Bears, e contém uma List<Animal> coleção de detalhes do urso. O segundo AnimalGroup é chamado Monkeys, e contém uma List<Animal> coleção de detalhes do macaco.

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

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <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>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Este é o código C# equivalente:

ListView listView = new ListView
{
    IsGroupingEnabled = true
};
listView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...

A aparência de cada item no ListView é definida definindo sua ItemTemplate propriedade como um DataTemplatearquivo . Para obter mais informações, consulte Definir a aparência do item.

A captura de tela a seguir mostra a exibição de ListView dados agrupados:

Screenshot of grouped data in a ListView.

Observação

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

Personalizar o cabeçalho do grupo

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

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="True">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding Name}"
                       BackgroundColor="LightGray"
                       FontSize="18"
                       FontAttributes="Bold" />
            </ViewCell>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    ...
</ListView>

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

Screenshot of a customized group header in a ListView.

Importante

A GroupHeaderTemplate propriedade é mutuamente exclusiva com a GroupDisplayBinding propriedade. Portanto, ambas as propriedades não devem ser definidas.

Grupo sem modelos

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

<ListView ItemsSource="{Binding Animals}"
          IsGroupingEnabled="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.

Controlar rolagem

ListView define dois ScrollTo métodos, que rolam itens para a exibição. Uma das sobrecargas rola o item especificado para a exibição, enquanto a outra rola o item especificado no grupo especificado para exibição. Ambas as sobrecargas têm argumentos adicionais que permitem especificar a posição exata do item após a conclusão da rolagem e se a rolagem deve ser animada.

ListView Define um evento que é acionado quando um ScrollToRequested dos ScrollTo métodos é chamado. O ScrollToRequestedEventArgs objeto que acompanha o ScrollToRequested evento tem muitas propriedades, incluindo ShouldAnimate, Element, Modee Position. Algumas dessas propriedades são definidas a partir dos argumentos especificados nas ScrollTo chamadas de método.

Além disso, ListView define um Scrolled evento que é acionado para indicar que a rolagem ocorreu. O ScrolledEventArgs objeto que acompanha o Scrolled evento tem ScrollX e ScrollY propriedades.

Detectar rolagem

ListView Define um Scrolled evento que é acionado para indicar que a rolagem ocorreu. A ItemsViewScrolledEventArgs classe, que representa o objeto que acompanha o Scrolled evento, define as seguintes propriedades:

  • ScrollX, do tipo double, representa a posição X da rolagem
  • ScrollY, do tipo double, representa a posição Y da rolagem.

O exemplo XAML a seguir mostra um que define um ListView manipulador de eventos para o Scrolled evento:

<ListView Scrolled="OnListViewScrolled">
    ...
</ListView>

Este é o código C# equivalente:

ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;

Neste exemplo de código, o manipulador de eventos é executado quando o OnListViewScrolledScrolled evento é acionado:

void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
    // Custom logic
}

Importante

O Scrolled evento é acionado para rolagens iniciadas pelo usuário e para rolagens programáticas.

Rolar um item para a exibição

O ScrollTo método rola o item especificado para exibição. Dado um ListView objeto chamado listView, o exemplo a seguir mostra como rolar o item Proboscis Monkey para exibição:

MonkeysViewModel viewModel = BindingContext as MonkeysViewModel;
Monkey monkey = viewModel.Monkeys.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, ScrollToPosition.MakeVisible, true);

Como alternativa, um item em dados agrupados pode ser rolado para a exibição especificando o item e o grupo. O exemplo a seguir mostra como rolar o item Macaco Probóscide no grupo Macacos para exibição:

GroupedAnimalsViewModel viewModel = BindingContext as GroupedAnimalsViewModel;
AnimalGroup group = viewModel.Animals.FirstOrDefault(a => a.Name == "Monkeys");
Animal monkey = group.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, group, ScrollToPosition.MakeVisible, true);

Observação

O ScrollToRequested evento é acionado quando o ScrollTo método é chamado.

Desativar animação de rolagem

Uma animação de rolagem é exibida ao rolar um item para a exibição. No entanto, essa animação pode ser desabilitada definindo o animatedScrollTo argumento do método como false:

listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: false);

Controlar a posição de rolagem

Ao rolar um item para a exibição, a posição exata do item após a rolagem ter sido concluída pode ser especificada com o positionScrollTo argumento dos métodos. Esse argumento aceita um membro de ScrollToPosition enumeração.

TornarVisível

O ScrollToPosition.MakeVisible membro indica que o item deve ser rolado até ficar visível na exibição:

listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: true);

Iniciar

O ScrollToPosition.Start membro indica que o item deve ser rolado até o início da exibição:

listView.ScrollTo(monkey, position: ScrollToPosition.Start, animate: true);

Centralizar

O ScrollToPosition.Center membro indica que o item deve ser rolado para o centro da exibição:

listView.ScrollTo(monkey, position: ScrollToPosition.Center, animate: true);

Encerrar

O ScrollToPosition.End membro indica que o item deve ser rolado até o final da exibição:

listView.ScrollTo(monkey, position: ScrollToPosition.End, animate: true);

Visibilidade da barra de rolagem

ListView define HorizontalScrollBarVisibility e VerticalScrollBarVisibility propriedades, que são apoiadas por propriedades vinculáveis. Essas propriedades obtêm ou definem um ScrollBarVisibility valor de enumeração que representa quando a barra de rolagem horizontal ou vertical está visível. A enumeração ScrollBarVisibility define os seguintes membros:

  • Default Indica o comportamento padrão da barra de rolagem para a plataforma e é o valor padrão para as HorizontalScrollBarVisibility propriedades And VerticalScrollBarVisibility .
  • Always indica que as barras de rolagem ficarão visíveis, mesmo quando o conteúdo se encaixar na exibição.
  • Never indica que as barras de rolagem não estarão visíveis, mesmo que o conteúdo não caiba na exibição.

Adicionar menus de contexto

ListViewOferece suporte a itens de menus de ViewCell.ContextActions contexto, que são definidos como MenuItem objetos que são adicionados à coleção no DataTemplate para cada item:

<ListView x:Name="listView"
          ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.ContextActions>
                    <MenuItem Text="Favorite"
                              Command="{Binding Source={x:Reference listView}, Path=BindingContext.FavoriteCommand}"
                              CommandParameter="{Binding}" />
                    <MenuItem Text="Delete"
                              Command="{Binding Source={x:Reference listView}, Path=BindingContext.DeleteCommand}"
                              CommandParameter="{Binding}" />
                </ViewCell.ContextActions>

                ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Os MenuItem objetos são revelados quando um item no é clicado com o botão direito do ListView mouse:

Screenshot of CollectionView context menu items.

Para obter mais informações sobre itens de menu, consulte Exibir itens de menu.

Deslizar para atualizar

ListView Oferece suporte à funcionalidade pull to refresh, que permite que os dados que estão sendo exibidos sejam atualizados puxando para baixo na lista de itens.

Para habilitar a atualização pull, defina a IsPullToRefreshEnabled propriedade como true. Quando uma atualização é acionada, ListView gera o Refreshing evento e a IsRefreshing propriedade será definida como true. O código necessário para atualizar o conteúdo do deve ser executado pelo manipulador para ListView o Refreshing evento ou pela ICommand implementação executada RefreshCommand . Depois que o é atualizado, a propriedade deve ser definida como false, ou o EndRefreshListView método deve ser chamado no ListView, para indicar que a IsRefreshing atualização está concluída.

O exemplo a seguir mostra um ListView que usa pull para atualizar:

<ListView ItemsSource="{Binding Animals}"
          IsPullToRefreshEnabled="true"
          RefreshCommand="{Binding RefreshCommand}"
          IsRefreshing="{Binding IsRefreshing}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                ...
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Neste exemplo, quando o usuário inicia uma atualização, o ICommand definido pela propriedade é executado, o RefreshCommand que deve atualizar os itens que estão sendo exibidos. Uma visualização de atualização é mostrada enquanto a atualização ocorre, que consiste em um círculo de progresso animado. O valor da IsRefreshing propriedade indica o estado atual da operação de atualização. Quando uma atualização é acionada, essa propriedade faz a transição automaticamente para true. Quando a atualização for concluída, você deverá redefinir a propriedade para false.