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.
Construído em células
Xamarin.Forms Vem com células integradas 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 aTextCell
s, mas incluem uma imagem à esquerda do texto.SwitchCell
Os controles são usados para apresentar e capturar estados ativados/desativados ou verdadeiro/falso.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
.
CélulaDeTexto
TextCell
é uma célula para exibir texto, opcionalmente com uma segunda linha como texto detalhado. A captura de tela a seguir mostra TextCell
itens no iOS e no Android:
TextCells são renderizados como controles nativos em tempo de execução, portanto, o desempenho é muito bom em comparação com um .ViewCell
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
o , pode ser usado para exibir texto e texto de detalhes secundários e oferece ótimo desempenho usando os controles nativos de cada plataforma. ImageCell
difere de TextCell
que exibe uma imagem à esquerda do texto.
A captura de tela a seguir mostra ImageCell
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 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 que você crie layouts de célula que não são compatíveis com as células internas. Por exemplo, você pode apresentar uma célula com dois rótulos com peso igual. A TextCell
seria insuficiente porque tem TextCell
um rótulo menor. A maioria das personalizações de células adiciona dados somente leitura adicionais (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 está aninhada dentro de um , que está dentro de
ListView.ItemTemplate
.DataTemplate
Este é o mesmo processo que usar qualquer célula interna. ViewCell
é o tipo da célula personalizada. O filho doDataTemplate
elemento deve ser da classe ou derivar delaViewCell
.- Dentro do , o layout pode ser gerenciado
ViewCell
por qualquer Xamarin.Forms layout. Neste exemplo, o layout é gerenciado por umStackLayout
, que permite que a cor de fundo seja personalizada.
Observação
Qualquer propriedade que seja associável pode ser vinculada dentro de StackLayout
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 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 do ItemTemplate
ListView é 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 às 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 da 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 para Xamarin.Forms coleta de lixo, o que, por sua vez, resultará na chamada de OnBindingContextChanged
substituição.
Como alternativa, os controles de interface do BindableProperty
usuário podem ser associados às instâncias para exibir seus valores, o que elimina a necessidade de substituir o OnBindingContextChanged
método.
Observação
Ao substituir OnBindingContextChanged
, certifique-se de que o método da OnBindingContextChanged
classe base seja chamado para que os delegados registrados recebam o BindingContextChanged
evento.
Em 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 os ListView
elementos is recycling 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 são alterados quando o contexto de associação é 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 reciclagem de células, consulte Estratégia de cache.