Compartir vía


Apariencia de ListView

Xamarin.FormsListView permite personalizar la presentación de la lista, además de las instancias ViewCell de cada fila de la lista.

Agrupación

Los grandes conjuntos de datos pueden resultar poco manejables cuando se presentan en una lista que se desplaza continuamente. La habilitación de la agrupación puede mejorar la experiencia del usuario en estos casos organizando mejor el contenido y activando controles específicos de la plataforma que facilitan la navegación por los datos.

Cuando la agrupación se activa para ListView, se agrega una fila de encabezado para cada grupo.

Para habilitar la agrupación:

  • Cree una lista de listas (una lista de grupos, cada grupo siendo una lista de elementos).
  • Establezca los ItemsSource de ListView en esa lista.
  • Establezca IsGroupingEnabled en true.
  • Establezca GroupDisplayBinding para enlazar a la propiedad de los grupos que se usan como título del grupo.
  • [Opcional] Establezca GroupShortNameBinding para enlazar a la propiedad de los grupos que se usan como nombre corto para el grupo. El nombre corto se usa para las listas de accesos directos (columna del lado derecho en iOS).

Empiece por crear una clase para los grupos:

public class PageTypeGroup : List<PageModel>
    {
        public string Title { get; set; }
        public string ShortName { get; set; } //will be used for jump lists
        public string Subtitle { get; set; }
        private PageTypeGroup(string title, string shortName)
        {
            Title = title;
            ShortName = shortName;
        }

        public static IList<PageTypeGroup> All { private set; get; }
    }

En el código anterior, All es la lista que se proporcionará a nuestro ListView como origen de enlace. Title y ShortName son las propiedades que se usarán para los encabezados de grupo.

En esta fase, All es una lista vacía. Agregue un constructor estático para que la lista se rellene en el inicio del programa:

static PageTypeGroup()
{
    List<PageTypeGroup> Groups = new List<PageTypeGroup> {
            new PageTypeGroup ("Alpha", "A"){
                new PageModel("Amelia", "Cedar", new switchCellPage(),""),
                new PageModel("Alfie", "Spruce", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Ava", "Pine", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Archie", "Maple", new switchCellPage(), "grapefruit.jpg")
            },
            new PageTypeGroup ("Bravo", "B"){
                new PageModel("Brooke", "Lumia", new switchCellPage(),""),
                new PageModel("Bobby", "Xperia", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Bella", "Desire", new switchCellPage(), "grapefruit.jpg"),
                new PageModel("Ben", "Chocolate", new switchCellPage(), "grapefruit.jpg")
            }
        };
        All = Groups; //set the publicly accessible list
}

En el código anterior, también podemos llamar a Add en elementos de Groups, que son instancias de tipo PageTypeGroup. Este método es posible porque PageTypeGroup hereda de List<PageModel>.

Este es el código XAML para mostrar la lista agrupada:

<?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.GroupingViewPage"
    <ContentPage.Content>
        <ListView  x:Name="GroupedView"
                   GroupDisplayBinding="{Binding Title}"
                   GroupShortNameBinding="{Binding ShortName}"
                   IsGroupingEnabled="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding Subtitle}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

Este XAML realiza las siguientes acciones:

  • Establecer GroupShortNameBinding en la propiedad ShortName definida en nuestra clase de grupo
  • Establecer GroupDisplayBinding en la propiedad Title definida en nuestra clase de grupo
  • Establecer IsGroupingEnabled en true
  • Cambió el ItemsSource de ListView a la lista agrupada

En esta captura de pantalla siguiente se muestra la interfaz de usuario resultante:

Ejemplo de agrupación de ListView

Personalización de la agrupación

Si la agrupación se ha habilitado en la lista, también se puede personalizar el encabezado del grupo.

Al igual que ListView tiene ItemTemplate para definir cómo se muestran las filas, ListView tiene un GroupHeaderTemplate.

Aquí se muestra un ejemplo de personalización del encabezado de grupo en 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.GroupingViewPage">
    <ContentPage.Content>
        <ListView x:Name="GroupedView"
                  GroupDisplayBinding="{Binding Title}"
                  GroupShortNameBinding="{Binding ShortName}"
                  IsGroupingEnabled="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding Subtitle}"
                              TextColor="#f35e20"
                              DetailColor="#503026" />
                </DataTemplate>
            </ListView.ItemTemplate>
            <!-- Group Header Customization-->
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Title}"
                              Detail="{Binding ShortName}"
                              TextColor="#f35e20"
                              DetailColor="#503026" />
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <!-- End Group Header Customization -->
        </ListView>
    </ContentPage.Content>
</ContentPage>

Encabezados y pies de página

Es posible que ListView presente un encabezado y pie de página que se desplazan con los elementos de la lista. El encabezado y el pie de página pueden ser cadenas de texto o un diseño más complicado. Este comportamiento es independiente de los grupos de secciones.

Puede establecer el Header o Footer en un valor de string, o bien puede establecerlos en un diseño más complejo. También hay propiedades HeaderTemplate y FooterTemplate que permiten crear diseños más complejos para el encabezado y pie de página que admiten el enlace de datos.

Para crear un encabezado o pie de página básico, solo tiene que establecer las propiedades de Encabezado o Pie de página en el texto que desea mostrar. Mediante código:

ListView HeaderList = new ListView()
{
    Header = "Header",
    Footer = "Footer"
};

En XAML:

<ListView x:Name="HeaderList" 
          Header="Header"
          Footer="Footer">
    ...
</ListView>

ListView con encabezado y pie de página

Para crear un encabezado y pie de página personalizados, defina las vistas Encabezado y Pie de página:

<ListView.Header>
    <StackLayout Orientation="Horizontal">
        <Label Text="Header"
               TextColor="Olive"
               BackgroundColor="Red" />
    </StackLayout>
</ListView.Header>
<ListView.Footer>
    <StackLayout Orientation="Horizontal">
        <Label Text="Footer"
               TextColor="Gray"
               BackgroundColor="Blue" />
    </StackLayout>
</ListView.Footer>

ListView con encabezado y pie de página personalizados

Visibilidad de la barra de desplazamiento

La clase ListView tiene propiedades HorizontalScrollBarVisibility y VerticalScrollBarVisibility, que obtienen o establecen un valor de ScrollBarVisibility que representa cuando la barra de desplazamiento horizontal o vertical está visible. Ambas propiedades se pueden establecer en los siguientes valores:

  • Default indica el comportamiento predeterminado de la barra de desplazamiento para la plataforma y es el valor predeterminado de las propiedades HorizontalScrollBarVisibility y VerticalScrollBarVisibility .
  • Always indica que las barras de desplazamiento estarán visibles, incluso cuando el contenido se ajusta en la vista.
  • Never indica que las barras de desplazamiento no están visibles, incluso si el contenido no encaja en la vista.

Separadores de filas

Las líneas separadoras se muestran entre elementos ListView de forma predeterminada en iOS y Android. Si prefiere ocultar las líneas de separador en iOS y Android, establezca la propiedad SeparatorVisibility en ListView. Las opciones de SeparatorVisibility son:

  • Valor predeterminado: muestra una línea separadora en iOS y Android.
  • Ninguno: oculta el separador en todas las plataformas.

Visibilidad predeterminada:

C#:

SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.Default;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="Default" />

ListView con separadores de fila predeterminados

Ninguna:

C#:

SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.None;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="None" />

ListView sin separadores de fila

También puede establecer el color de la línea separadora mediante la propiedad SeparatorColor:

C#:

SeparatorDemoListView.SeparatorColor = Color.Green;

XAML:

<ListView x:Name="SeparatorDemoListView" SeparatorColor="Green" />

ListView con separadores de fila verdes

Nota:

Al establecer cualquiera de estas propiedades en Android después de cargar ListView se produce una gran penalización de rendimiento.

Altura de la fila

Todas las filas de un control ListView tienen el mismo alto de forma predeterminada. ListView tiene dos propiedades que se pueden usar para cambiar ese comportamiento:

  • HasUnevenRows: valor true/false, las filas tienen diferentes alturas si se establece en true. Tiene como valor predeterminado false.
  • RowHeight: establece el alto de cada fila cuando HasUnevenRows es false.

Puede establecer el alto de todas las filas estableciendo la propiedad RowHeight en el ListView.

Alto de fila fijo personalizado

C#:

RowHeightDemoListView.RowHeight = 100;

XAML:

<ListView x:Name="RowHeightDemoListView" RowHeight="100" />

ListView con alto fijo de fila

Filas desiguales

Si desea que las filas individuales tengan diferentes alturas, puede establecer la propiedad HasUnevenRows en true. Los alto de fila no tienen que establecerse manualmente una vez que HasUnevenRows se ha establecido en true, ya que el alto se calculará automáticamente mediante Xamarin.Forms.

C#:

RowHeightDemoListView.HasUnevenRows = true;

XAML:

<ListView x:Name="RowHeightDemoListView" HasUnevenRows="true" />

ListView con filas desiguales

Cambiar el tamaño de las filas en tiempo de ejecución

Las filas de ListView individuales se pueden cambiar de tamaño mediante programación en tiempo de ejecución, siempre que la propiedad HasUnevenRows esté establecida en true. El método Cell.ForceUpdateSize actualiza el tamaño de una celda, incluso cuando no está visible actualmente, como se muestra en el ejemplo de código siguiente:

void OnImageTapped (object sender, EventArgs args)
{
    var image = sender as Image;
    var viewCell = image.Parent.Parent as ViewCell;

    if (image.HeightRequest < 250) {
        image.HeightRequest = image.Height + 100;
        viewCell.ForceUpdateSize ();
    }
}

El controlador de eventos OnImageTapped se ejecuta en respuesta a un Image en una celda que se pulsa y aumenta el tamaño de la Image que se muestra en la celda para que se vea fácilmente.

ListView con cambio de tamaño de fila en tiempo de ejecución

Advertencia

El uso excesivo del cambio de tamaño de las filas en tiempo de ejecución puede provocar una degradación del rendimiento.