Compartilhar via


Personalizando a aparência da célula ListView

A Xamarin.FormsListView classe é usada para apresentar listas roláveis, que podem ser personalizadas através do uso de ViewCell elementos. Um ViewCell elemento pode exibir texto e imagens, indicar um estado verdadeiro/falso e receber entrada do usuário.

Construído em células

Xamarin.Forms vem com células internas que funcionam para muitas aplicações:

  • TextCell Os controles são usados para exibir texto com uma segunda linha opcional para texto detalhado.
  • ImageCell Os controles são semelhantes a S, TextCellmas incluem uma imagem à esquerda do texto.
  • SwitchCell Os controles são usados para apresentar e capturar estados on/off ou true/false.
  • EntryCell Os controles são usados para apresentar dados de texto que o usuário pode editar.

Os SwitchCell controles e EntryCell são mais comumente usados no contexto de um TableViewarquivo .

CélulaDeTexto

TextCell é uma célula para exibir texto, opcionalmente com uma segunda linha como texto de detalhe. A captura de tela a seguir mostra TextCell itens no iOS e Android:

Exemplo padrão de TextCell

TextCells são renderizados como controles nativos em tempo de execução, portanto, o desempenho é muito bom em comparação com um ViewCellarquivo . TextCells são personalizáveis, permitindo que você defina as seguintes propriedades:

  • Text – o texto que é mostrado na primeira linha, em fonte grande.
  • Detail – o texto que é mostrado abaixo da primeira linha, em uma fonte menor.
  • TextColor – a cor do texto.
  • DetailColor – a cor do texto detalhado

A captura de tela a seguir mostra TextCell itens com propriedades de cor personalizadas:

Exemplo de TextCell personalizado

CélulaDeImagem

ImageCell, como TextCell, pode ser usado para exibir texto e texto de detalhe secundário, e oferece ótimo desempenho usando os controles nativos de cada plataforma. ImageCell difere do TextCell que ele exibe uma imagem à esquerda do texto.

A captura de tela a seguir mostra ImageCell itens no iOS e Android:

ImageCell é útil quando você precisa exibir uma lista de dados com um aspecto visual, como uma lista de contatos ou filmes. ImageCells são personalizáveis, permitindo que você defina:

  • Text – o texto que é mostrado na primeira linha, em fonte grande
  • Detail – o texto que é mostrado abaixo da primeira linha, em uma fonte menor
  • TextColor – a cor do texto
  • DetailColor – a cor do texto detalhado
  • ImageSource – a imagem a ser exibida ao lado do texto

A captura de tela a seguir mostra ImageCell itens com propriedades de cor personalizadas:

Células personalizadas

As células personalizadas permitem criar layouts de célula que não são suportados pelas células internas. Por exemplo, convém apresentar uma célula com dois rótulos que tenham peso igual. A TextCell seria insuficiente porque o TextCell tem um rótulo que é menor. A maioria das personalizações de célula adiciona dados adicionais somente leitura (como rótulos adicionais, imagens ou outras informações de exibição).

Todas as células personalizadas devem derivar de ViewCell, a mesma classe base que todos os tipos de célula internos usam.

Xamarin.Forms oferece um comportamento de cache no controle que pode melhorar o ListView desempenho de rolagem para alguns tipos de células personalizadas.

A captura de tela a seguir mostra um exemplo de uma célula personalizada:

XAML

A célula personalizada mostrada na captura de tela anterior pode ser criada com o seguinte XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="demoListView.ImageCellPage">
    <ContentPage.Content>
        <ListView  x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout BackgroundColor="#eee"
                        Orientation="Vertical">
                            <StackLayout Orientation="Horizontal">
                                <Image Source="{Binding image}" />
                                <Label Text="{Binding title}"
                                TextColor="#f35e20" />
                                <Label Text="{Binding subtitle}"
                                HorizontalOptions="EndAndExpand"
                                TextColor="#503026" />
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

O XAML funciona da seguinte maneira:

  • A célula personalizada é aninhada dentro de um DataTemplate, que está dentro ListView.ItemTemplatede . Esse é o mesmo processo que usar qualquer célula interna.
  • ViewCell é o tipo da célula personalizada. O filho do DataTemplate elemento deve ser de, ou derivar de, a ViewCell classe.
  • Dentro do , o ViewCelllayout pode ser gerenciado por qualquer Xamarin.Forms layout. Neste exemplo, o layout é gerenciado por um StackLayout, que permite que a cor do plano de fundo seja personalizada.

Observação

Qualquer propriedade que seja vinculável pode ser vinculada dentro de StackLayout uma célula personalizada. No entanto, esse recurso não é mostrado no exemplo XAML.

Código

Uma célula personalizada também pode ser criada no código. Primeiro, uma classe personalizada que deriva de ViewCell deve ser criada:

public class CustomCell : ViewCell
    {
        public CustomCell()
        {
            //instantiate each of our views
            var image = new Image ();
            StackLayout cellWrapper = new StackLayout ();
            StackLayout horizontalLayout = new StackLayout ();
            Label left = new Label ();
            Label right = new Label ();

            //set bindings
            left.SetBinding (Label.TextProperty, "title");
            right.SetBinding (Label.TextProperty, "subtitle");
            image.SetBinding (Image.SourceProperty, "image");

            //Set properties for desired design
            cellWrapper.BackgroundColor = Color.FromHex ("#eee");
            horizontalLayout.Orientation = StackOrientation.Horizontal;
            right.HorizontalOptions = LayoutOptions.EndAndExpand;
            left.TextColor = Color.FromHex ("#f35e20");
            right.TextColor = Color.FromHex ("503026");

            //add views to the view hierarchy
            horizontalLayout.Children.Add (image);
            horizontalLayout.Children.Add (left);
            horizontalLayout.Children.Add (right);
            cellWrapper.Children.Add (horizontalLayout);
            View = cellWrapper;
        }
    }

No construtor de página, a propriedade ListView ItemTemplate é definida como a DataTemplate com o CustomCell tipo especificado:

public partial class ImageCellPage : ContentPage
    {
        public ImageCellPage ()
        {
            InitializeComponent ();
            listView.ItemTemplate = new DataTemplate (typeof(CustomCell));
        }
    }

Alterações de contexto de vinculação

Ao vincular a instâncias de um tipo de BindableProperty célula personalizado, os controles de interface do usuário que exibem os BindableProperty valores devem usar a OnBindingContextChanged substituição para definir os dados a serem exibidos em cada célula, em vez do construtor de célula, conforme demonstrado no exemplo de código a seguir:

public class CustomCell : ViewCell
{
    Label nameLabel, ageLabel, locationLabel;

    public static readonly BindableProperty NameProperty =
        BindableProperty.Create ("Name", typeof(string), typeof(CustomCell), "Name");
    public static readonly BindableProperty AgeProperty =
        BindableProperty.Create ("Age", typeof(int), typeof(CustomCell), 0);
    public static readonly BindableProperty LocationProperty =
        BindableProperty.Create ("Location", typeof(string), typeof(CustomCell), "Location");

    public string Name
    {
        get { return(string)GetValue (NameProperty); }
        set { SetValue (NameProperty, value); }
    }

    public int Age
    {
        get { return(int)GetValue (AgeProperty); }
        set { SetValue (AgeProperty, value); }
    }

    public string Location
    {
        get { return(string)GetValue (LocationProperty); }
        set { SetValue (LocationProperty, value); }
    }
    ...

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

        if (BindingContext != null)
        {
            nameLabel.Text = Name;
            ageLabel.Text = Age.ToString ();
            locationLabel.Text = Location;
        }
    }
}

A OnBindingContextChanged substituição será chamada quando o BindingContextChanged evento for acionado, em resposta à alteração do valor da BindingContext propriedade. Portanto, quando as BindingContext alterações, os controles de interface do usuário que exibem os BindableProperty valores devem definir seus dados. Observe que o deve ser verificado BindingContext para um null valor, pois isso pode ser definido por Xamarin.Forms para coleta de lixo, o OnBindingContextChanged que, por sua vez, resultará na substituição sendo chamada.

Como alternativa, os controles de interface do BindableProperty usuário podem se vincular às instâncias para exibir seus valores, o que elimina a necessidade de substituir o OnBindingContextChanged método.

Observação

Ao substituir OnBindingContextChangedo , verifique se o método da OnBindingContextChanged classe base é chamado para que os delegados registrados recebam o BindingContextChanged evento.

Em XAML, a vinculação do tipo de célula personalizada aos dados pode ser obtida conforme mostrado no exemplo de código a seguir:

<ListView x:Name="listView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:CustomCell Name="{Binding Name}" Age="{Binding Age}" Location="{Binding Location}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Isso vincula as Namepropriedades , Agee Location vinculáveis na CustomCell instância às propriedades , Agee NameLocation de cada objeto na coleção subjacente.

A associação equivalente em C# é mostrada no exemplo de código a seguir:

var customCell = new DataTemplate (typeof(CustomCell));
customCell.SetBinding (CustomCell.NameProperty, "Name");
customCell.SetBinding (CustomCell.AgeProperty, "Age");
customCell.SetBinding (CustomCell.LocationProperty, "Location");

var listView = new ListView
{
    ItemsSource = people,
    ItemTemplate = customCell
};

No iOS e no Android, se o ListView estiver reciclando elementos e a célula personalizada usar um renderizador personalizado, o renderizador personalizado deverá implementar corretamente a notificação de alteração de propriedade. Quando as células são reutilizadas, seus valores de propriedade serão alterados quando o contexto de vinculação for atualizado para o de uma célula disponível, com PropertyChanged eventos sendo gerados. Para obter mais informações, consulte Personalizando uma ViewCell. Para obter mais informações sobre reciclagem de células, consulte Estratégia de cache.