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
deListView
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 propiedadShortName
definida en nuestra clase de grupo - Establecer
GroupDisplayBinding
en la propiedadTitle
definida en nuestra clase de grupo - Establecer
IsGroupingEnabled
en true - Cambió el
ItemsSource
deListView
a la lista agrupada
En esta captura de pantalla siguiente se muestra la interfaz de usuario resultante:
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>
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>
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 propiedadesHorizontalScrollBarVisibility
yVerticalScrollBarVisibility
.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" />
Ninguna:
C#:
SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.None;
XAML:
<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="None" />
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" />
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
: valortrue
/false
, las filas tienen diferentes alturas si se establece entrue
. Tiene como valor predeterminadofalse
.RowHeight
: establece el alto de cada fila cuandoHasUnevenRows
esfalse
.
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" />
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" />
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.
Advertencia
El uso excesivo del cambio de tamaño de las filas en tiempo de ejecución puede provocar una degradación del rendimiento.