Personalizar el aspecto de las celdas de ListViewCustomizing ListView Cell Appearance

Descargar ejemplo Descargar el ejemploDownload Sample Download the sample

La :::no-loc(Xamarin.Forms)::: ListView clase se usa para presentar listas desplazables, que se pueden personalizar mediante el uso de ViewCell elementos.The :::no-loc(Xamarin.Forms)::: ListView class is used to present scrollable lists, which can be customized through the use of ViewCell elements. Un ViewCell elemento puede mostrar texto e imágenes, indicar un estado verdadero/falso y recibir datos proporcionados por el usuario.A ViewCell element can display text and images, indicate a true/false state, and receive user input.

Celdas integradasBuilt in Cells

:::no-loc(Xamarin.Forms)::: incluye celdas integradas que funcionan para muchas aplicaciones::::no-loc(Xamarin.Forms)::: comes with built-in cells that work for many applications:

  • TextCell los controles se usan para mostrar texto con una segunda línea opcional para el texto detallado.TextCell controls are used for displaying text with an optional second line for detail text.
  • ImageCell los controles son similares a TextCell s, pero incluyen una imagen a la izquierda del texto.ImageCell controls are similar to TextCells but include an image to the left of the text.
  • SwitchCell los controles se usan para presentar y capturar Estados de activado/desactivado o verdadero/falso.SwitchCell controls are used to present and capture on/off or true/false states.
  • EntryCell los controles se usan para presentar datos de texto que el usuario puede editar.EntryCell controls are used to present text data that the user can edit.

Los SwitchCell EntryCell controles y se utilizan con más frecuencia en el contexto de un TableView .The SwitchCell and EntryCell controls are more commonly used in the context of a TableView.

TextCellTextCell

TextCell es una celda para mostrar texto, opcionalmente con una segunda línea como texto detallado.TextCell is a cell for displaying text, optionally with a second line as detail text. En la captura de pantalla siguiente se muestran TextCell los elementos de iOS y Android:The following screenshot shows TextCell items on iOS and Android:

Ejemplo de TextCell predeterminado

TextCells se representan como controles nativos en tiempo de ejecución, por lo que el rendimiento es muy bueno en comparación con un personalizado ViewCell .TextCells are rendered as native controls at runtime, so performance is very good compared to a custom ViewCell. Los TextCells son personalizables, lo que le permite establecer las siguientes propiedades:TextCells are customizable, allowing you to set the following properties:

  • Text–texto que se muestra en la primera línea, en una fuente grande.Text – the text that is shown on the first line, in large font.
  • Detail–texto que se muestra debajo de la primera línea, en una fuente menor.Detail – the text that is shown underneath the first line, in a smaller font.
  • TextColor–color del texto.TextColor – the color of the text.
  • DetailColor–color del texto de detalleDetailColor – the color of the detail text

La siguiente captura de pantalla muestra TextCell los elementos con propiedades de color personalizadas:The following screenshot shows TextCell items with customized color properties:

Ejemplo de TextCell personalizado

ImageCellImageCell

ImageCell, como TextCell , se puede usar para mostrar texto y texto de detalle secundario, y ofrece un gran rendimiento mediante el uso de los controles nativos de cada plataforma.ImageCell, like TextCell, can be used for displaying text and secondary detail text, and it offers great performance by using each platform's native controls. ImageCell se diferencia de TextCell en que muestra una imagen a la izquierda del texto.ImageCell differs from TextCell in that it displays an image to the left of the text.

En la captura de pantalla siguiente se muestran ImageCell los elementos de iOS y Android: "default ImageCell example"The following screenshot shows ImageCell items on iOS and Android: "Default ImageCell Example"

ImageCell resulta útil cuando es necesario mostrar una lista de datos con un aspecto visual, como una lista de contactos o películas.ImageCell is useful when you need to display a list of data with a visual aspect, such as a list of contacts or movies. ImageCelllos s son personalizables, lo que permite establecer:ImageCells are customizable, allowing you to set:

  • Text–texto que se muestra en la primera línea, en una fuente grande.Text – the text that is shown on the first line, in large font
  • Detail–texto que se muestra debajo de la primera línea, en una fuente menor.Detail – the text that is shown underneath the first line, in a smaller font
  • TextColor–color del texto.TextColor – the color of the text
  • DetailColor–color del texto de detalleDetailColor – the color of the detail text
  • ImageSource–la imagen que se va a mostrar junto al texto.ImageSource – the image to display next to the text

La siguiente captura de pantalla muestra ImageCell los elementos con propiedades de color personalizadas: "ejemplo de ImageCell personalizado"The following screenshot shows ImageCell items with customized color properties: "Customized ImageCell Example"

Celdas personalizadasCustom Cells

Las celdas personalizadas permiten crear diseños de celda que no son compatibles con las celdas integradas.Custom cells allow you to create cell layouts that aren't supported by the built-in cells. Por ejemplo, puede que desee presentar una celda con dos etiquetas que tengan el mismo peso.For example, you may want to present a cell with two labels that have equal weight. Un TextCell no sería suficiente porque TextCell tiene una etiqueta menor.A TextCell would be insufficient because the TextCell has one label that is smaller. La mayoría de las personalizaciones de celda agregan datos de solo lectura adicionales (como etiquetas adicionales, imágenes u otra información de presentación).Most cell customizations add additional read-only data (such as additional labels, images or other display information).

Todas las celdas personalizadas se deben derivar de ViewCell , la misma clase base que usan todos los tipos de celdas integrados.All custom cells must derive from ViewCell, the same base class that all of the built-in cell types use.

:::no-loc(Xamarin.Forms)::: ofrece un comportamiento de almacenamiento en caché en el ListView control que puede mejorar el rendimiento del desplazamiento para algunos tipos de celdas personalizadas.:::no-loc(Xamarin.Forms)::: offers a caching behavior on the ListView control which can improve scrolling performance for some types of custom cells.

En la captura de pantalla siguiente se muestra un ejemplo de una celda personalizada:The following screenshot shows an example of a custom cell:

"Ejemplo de celda personalizada""Custom Cell Example"

XAMLXAML

La celda personalizada que se muestra en la captura de pantalla anterior se puede crear con el código XAML siguiente:The custom cell shown in the previous screenshot can be created with the following 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>

El código XAML funciona de la siguiente manera:The XAML works as follows:

  • La celda personalizada está anidada dentro de un DataTemplate , que está dentro de ListView.ItemTemplate .The custom cell is nested inside a DataTemplate, which is inside ListView.ItemTemplate. Este es el mismo proceso que el uso de cualquier celda integrada.This is the same process as using any built-in cell.
  • ViewCell es el tipo de la celda personalizada.ViewCell is the type of the custom cell. El elemento secundario del DataTemplate elemento debe ser de la clase o derivarse de ella ViewCell .The child of the DataTemplate element must be of, or derive from, the ViewCell class.
  • Dentro de ViewCell , el diseño se puede administrar con cualquier :::no-loc(Xamarin.Forms)::: diseño.Inside the ViewCell, layout can be managed by any :::no-loc(Xamarin.Forms)::: layout. En este ejemplo, el diseño se administra mediante un StackLayout , que permite personalizar el color de fondo.In this example, layout is managed by a StackLayout, which allows the background color to be customized.

Nota

Cualquier propiedad de StackLayout que se pueda enlazar se puede enlazar dentro de una celda personalizada.Any property of StackLayout that is bindable can be bound inside a custom cell. Sin embargo, esta funcionalidad no se muestra en el ejemplo de XAML.However, this capability is not shown in the XAML example.

CódigoCode

También se puede crear una celda personalizada en el código.A custom cell can also be created in code. En primer lugar, se debe crear una clase personalizada derivada de ViewCell :First, a custom class that derives from ViewCell must be created:

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;
        }
    }

En el constructor de la página, la ItemTemplate propiedad del objeto ListView está establecida en DataTemplate con el CustomCell tipo especificado:In the page constructor, the ListView's ItemTemplate property is set to a DataTemplate with the CustomCell type specified:

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

Cambios de contexto de enlaceBinding Context Changes

Al enlazar a las instancias de un tipo de celda personalizado BindableProperty , los controles de interfaz de usuario que muestran los BindableProperty valores deben usar la OnBindingContextChanged invalidación para establecer los datos que se van a mostrar en cada celda, en lugar del constructor de celda, como se muestra en el ejemplo de código siguiente:When binding to a custom cell type's BindableProperty instances, the UI controls displaying the BindableProperty values should use the OnBindingContextChanged override to set the data to be displayed in each cell, rather than the cell constructor, as demonstrated in the following code example:

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;
        }
    }
}

Se OnBindingContextChanged llamará a la invalidación cuando se BindingContextChanged desencadene el evento, en respuesta al valor de la BindingContext propiedad que cambia.The OnBindingContextChanged override will be called when the BindingContextChanged event fires, in response to the value of the BindingContext property changing. Por consiguiente, cuando BindingContext cambia, los controles de la interfaz de usuario que muestran los BindableProperty valores deben establecer sus datos.Therefore, when the BindingContext changes, the UI controls displaying the BindableProperty values should set their data. Tenga en cuenta que BindingContext debe comprobarse un null valor, ya que se puede establecer mediante :::no-loc(Xamarin.Forms)::: para la recolección de elementos no utilizados, lo que, a su vez, dará lugar a la OnBindingContextChanged invalidación.Note that the BindingContext should be checked for a null value, as this can be set by :::no-loc(Xamarin.Forms)::: for garbage collection, which in turn will result in the OnBindingContextChanged override being called.

Como alternativa, los controles de interfaz de usuario se pueden enlazar a las BindableProperty instancias para mostrar sus valores, lo que elimina la necesidad de invalidar el OnBindingContextChanged método.Alternatively, UI controls can bind to the BindableProperty instances to display their values, which removes the need to override the OnBindingContextChanged method.

Nota

Al reemplazar OnBindingContextChanged , asegúrese de que se llama al método de la clase base OnBindingContextChanged para que los delegados registrados reciban el BindingContextChanged evento.When overriding OnBindingContextChanged, ensure that the base class's OnBindingContextChanged method is called so that registered delegates receive the BindingContextChanged event.

En XAML, el enlace del tipo de celda personalizado a los datos se puede lograr tal y como se muestra en el ejemplo de código siguiente:In XAML, binding the custom cell type to data can be achieved as shown in the following code example:

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

Esto enlaza las Name propiedades, Age y Location enlazables en la instancia de CustomCell , a las Name propiedades, Age y Location de cada objeto de la colección subyacente.This binds the Name, Age, and Location bindable properties in the CustomCell instance, to the Name, Age, and Location properties of each object in the underlying collection.

En el ejemplo de código siguiente se muestra el enlace equivalente en C#:The equivalent binding in C# is shown in the following code example:

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
};

En iOS y Android, si el ListView elemento está reciclando elementos y la celda personalizada usa un representador personalizado, el representador personalizado debe implementar correctamente la notificación de cambio de propiedad.On iOS and Android, if the ListView is recycling elements and the custom cell uses a custom renderer, the custom renderer must correctly implement property change notification. Cuando se reutilizan las celdas, sus valores de propiedad cambiarán cuando el contexto de enlace se actualice al de una celda disponible, con PropertyChanged los eventos que se generan.When cells are reused their property values will change when the binding context is updated to that of an available cell, with PropertyChanged events being raised. Para obtener más información, consulte Personalización de un ViewCell.For more information, see Customizing a ViewCell. Para obtener más información sobre el reciclaje de celdas, vea estrategia de almacenamiento en caché.For more information about cell recycling, see Caching Strategy.