Personalizando a aparência da célula ListView
A Xamarin.FormsListView
classe é usada para apresentar listas roláveis, que podem ser personalizadas por meio do uso de ViewCell
elementos. Um ViewCell
elemento pode exibir texto e imagens, indicar um estado verdadeiro/falso e receber entrada do usuário.
Células internas
Xamarin.Forms vem com células internas que funcionam para muitos aplicativos:
TextCell
os controles são usados para exibir texto com uma segunda linha opcional para texto detalhado.ImageCell
os controles são semelhantes aTextCell
s, mas incluem uma imagem à esquerda do texto.SwitchCell
os controles são usados para apresentar e capturar estados ativados/desativados ou verdadeiros/falsos.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 TableView
.
TextCell
TextCell
é uma célula para exibir texto, opcionalmente com uma segunda linha como texto detalhado. A captura de tela a seguir mostra TextCell
os itens no iOS e no Android:
TextCells são renderizados como controles nativos em runtime, portanto, o desempenho é muito bom em comparação com um personalizado ViewCell
. TextCells são personalizáveis, permitindo que você defina as seguintes propriedades:
Text
– o texto mostrado na primeira linha, em fonte grande.Detail
– o texto mostrado abaixo da primeira linha, em uma fonte menor.TextColor
– a cor do texto.DetailColor
– a cor do texto de detalhes
A captura de tela a seguir mostra TextCell
itens com propriedades de cores personalizadas:
ImageCell
ImageCell
, como TextCell
, pode ser usado para exibir texto e texto de detalhes secundários e oferece um ótimo desempenho usando os controles nativos de cada plataforma. ImageCell
difere de TextCell
em que exibe uma imagem à esquerda do texto.
A captura de tela a seguir mostra ImageCell
os itens no iOS e no Android:
ImageCell
é útil quando você precisa exibir uma lista de dados com um aspecto visual, como uma lista de contatos ou filmes. ImageCell
s são personalizáveis, permitindo que você defina:
Text
– o texto mostrado na primeira linha, em fonte grandeDetail
– o texto mostrado abaixo da primeira linha, em uma fonte menorTextColor
– a cor do textoDetailColor
– a cor do texto de detalhesImageSource
– a imagem a ser exibida ao lado do texto
A captura de tela a seguir mostra ImageCell
itens com propriedades de cores personalizadas:
Células personalizadas
As células personalizadas permitem que você crie layouts de célula que não são compatíveis com as células internas. Por exemplo, talvez você queira apresentar uma célula com dois rótulos com peso igual. Um TextCell
seria insuficiente porque o TextCell
tem um rótulo menor. A maioria das personalizações de células adicionais 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élulas 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á dentroListView.ItemTemplate
de . Esse é o mesmo processo que usar qualquer célula interna. ViewCell
é o tipo da célula personalizada. O filho doDataTemplate
elemento deve ser de ou derivar daViewCell
classe .- Dentro do , o
ViewCell
layout pode ser gerenciado por qualquer Xamarin.Forms layout. Neste exemplo, o layout é gerenciado por umStackLayout
, que permite que a cor da tela de fundo seja personalizada.
Observação
Qualquer propriedade que StackLayout
seja associável pode ser associada dentro de uma célula personalizada. No entanto, essa funcionalidade não é mostrada no exemplo XAML.
Código
Uma célula personalizada também pode ser criada em código. Primeiro, uma classe personalizada derivada 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 um 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 associação
Ao associar a instâncias de um tipo de célula personalizado, os controles de interface do BindableProperty
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 evento for acionado BindingContextChanged
, em resposta ao valor da BindingContext
propriedade mudando. Portanto, quando o BindingContext
é alterado, os controles de interface do usuário que exibem os BindableProperty
valores devem definir seus dados. Observe que o BindingContext
deve ser verificado quanto a 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 que está sendo chamada.
Como alternativa, os controles de interface do BindableProperty
usuário podem se associar às instâncias para exibir seus valores, o que remove a necessidade de substituir o OnBindingContextChanged
método.
Observação
Ao substituir OnBindingContextChanged
, verifique se o método da OnBindingContextChanged
classe base é chamado para que os delegados registrados recebam o BindingContextChanged
evento.
No XAML, a associaçã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 associa as Name
propriedades , Age
e Location
associáveis na CustomCell
instância, às Name
propriedades , Age
e Location
de cada objeto na coleção subjacente.
A associação equivalente em C# é mostrada no seguinte exemplo de código:
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 forem reutilizados, seus valores de propriedade serão alterados quando o contexto de associação for atualizado para o de uma célula disponível, com PropertyChanged
eventos sendo gerados. Para obter mais informações, consulte Personalizando um ViewCell. Para obter mais informações sobre a reciclagem de células, consulte Estratégia de cache.