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,TextCell
mas 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 TableView
arquivo .
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:
TextCells são renderizados como controles nativos em tempo de execução, portanto, o desempenho é muito bom em comparação com um ViewCell
arquivo . 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:
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. ImageCell
s são personalizáveis, permitindo que você defina:
Text
– o texto que é mostrado na primeira linha, em fonte grandeDetail
– o texto que é mostrado abaixo da primeira linha, em uma fonte menorTextColor
– a cor do textoDetailColor
– a cor do texto detalhadoImageSource
– 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á 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 de, aViewCell
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 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 OnBindingContextChanged
o , 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 Name
propriedades , Age
e Location
vinculáveis na CustomCell
instância às propriedades , Age
e Name
Location
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.