Interactividad de ListView
La clase Xamarin.FormsListView
admite la interacción del usuario con los datos que presenta.
Selección y pulsaciones
El modo de selección ListView
se controla estableciendo la propiedad ListView.SelectionMode
en un valor de la enumeración ListViewSelectionMode
:
Single
indica que se puede seleccionar un solo elemento, con el elemento seleccionado resaltado. Este es el valor predeterminado.None
indica que no se puede seleccionar ningún elemento.
Cuando un usuario pulsa un elemento, se desencadenan dos eventos:
ItemSelected
se activa cuando se selecciona un nuevo elemento.ItemTapped
se activa cuando se pulsa un elemento.
Al pulsar el mismo elemento dos veces se activarán dos eventos de ItemTapped
, pero solo se activará un solo evento ItemSelected
.
Nota:
La clase ItemTappedEventArgs
, que contiene los argumentos del evento ItemTapped
, tiene propiedades Group
y Item
, y una propiedad ItemIndex
cuyo valor representa el índice en la ListView
del elemento pulsado. Del mismo modo, la clase SelectedItemChangedEventArgs
, que contiene los argumentos del evento ItemSelected
, tiene una propiedad SelectedItem
, y una propiedad SelectedItemIndex
cuyo valor representa el índice en la ListView
del elemento seleccionado.
Cuando la propiedad SelectionMode
se establece en Single
, los elementos de la ListView
se pueden seleccionar, los eventos ItemSelected
y ItemTapped
se activarán, y la propiedad SelectedItem
se establecerá en el valor del elemento seleccionado.
Cuando la propiedad SelectionMode
se fija en None
, los elementos de la ListView
no podrán seleccionarse, el evento ItemSelected
no se activará y la propiedad SelectedItem
permanecerá null
. Sin embargo, los eventos ItemTapped
seguirán activándose y el elemento sobre el que se haya pulsado aparecerá brevemente resaltado durante la pulsación.
Cuando se haya seleccionado un elemento y la propiedad SelectionMode
se cambie de Single
a None
, la propiedad SelectedItem
se fijará en null
y el evento ItemSelected
se activará con un elemento null
.
Las capturas de pantalla siguientes muestran un elemento ListView
con el modo de selección predeterminado:
Deshabilitar selección
Para deshabilitar la selección ListView
ajuste la propiedad SelectionMode
a None
:
<ListView ... SelectionMode="None" />
var listView = new ListView { ... SelectionMode = ListViewSelectionMode.None };
acciones de contexto
A menudo, los usuarios querrán realizar una acción en un ListView
. Por ejemplo, considere una lista de correos electrónicos en la aplicación Mail. En iOS, puede deslizar el dedo para eliminar un mensaje:
Las acciones contextuales pueden implementarse en C# y XAML. A continuación encontrará guías específicas para ambos, pero antes echemos un vistazo a algunos detalles clave de la aplicación de ambos.
Las Acciones de Contexto se crean utilizando elementos MenuItem
. Los eventos de pulsación de los objetos MenuItems
los genera el propio MenuItem
, no el ListView
. Esto es diferente de cómo se gestionan los eventos de pulsación para las celdas, donde el ListView
genera el evento en lugar de la celda. Dado que genera el evento ListView
, su controlador de eventos recibe información clave, como el elemento seleccionado o pulsado.
De forma predeterminada, un MenuItem
no tiene forma de saber a qué celda pertenece. La propiedad CommandParameter
está disponible en MenuItem
para almacenar objetos, como el objeto detrás del MenuItem
de ViewCell
. La propiedad CommandParameter
se puede establecer tanto en XAML como en C#.
XAML
Los elementos MenuItem
se pueden crear en una colección XAML. En el código XAML siguiente se muestra una celda personalizada con dos acciones de contexto implementadas:
<ListView x:Name="ContextDemoList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="OnMore"
CommandParameter="{Binding .}"
Text="More" />
<MenuItem Clicked="OnDelete"
CommandParameter="{Binding .}"
Text="Delete" IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Padding="15,0">
<Label Text="{Binding title}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
En el archivo de código subyacente, asegúrese de que los métodos Clicked
se implementan:
public void OnMore (object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");
}
public void OnDelete (object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");
}
Nota:
El NavigationPageRenderer
para Android tiene un método UpdateMenuItemIcon
reemplazable que se puede usar para cargar iconos desde un Drawable
personalizado. Esta invalidación permite usar imágenes SVG como iconos en instancias de MenuItem
en Android.
Código
Las acciones de contexto se pueden implementar en cualquier subclase Cell
(siempre que no se use como encabezado de grupo) creando instancias MenuItem
y agregándolas a la colección ContextActions
para la celda. Puede configurar las siguientes propiedades para la acción de contexto:
- Texto: la cadena que aparece en el elemento de menú.
- Hacer clic: el evento cuando se haga clic en el elemento.
- IsDestructive: (opcional) cuando es true el elemento se representa de forma diferente en iOS.
Se pueden agregar varias acciones de contexto a una celda, pero solo debe haber una IsDestructive
establecida en true
. En el código siguiente se muestra cómo se agregarían las acciones de contexto a un ViewCell
:
var moreAction = new MenuItem { Text = "More" };
moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
moreAction.Clicked += async (sender, e) =>
{
var mi = ((MenuItem)sender);
Debug.WriteLine("More Context Action clicked: " + mi.CommandParameter);
};
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
deleteAction.Clicked += async (sender, e) =>
{
var mi = ((MenuItem)sender);
Debug.WriteLine("Delete Context Action clicked: " + mi.CommandParameter);
};
// add to the ViewCell's ContextActions property
ContextActions.Add (moreAction);
ContextActions.Add (deleteAction);
Deslizar para actualizar
Los usuarios esperan que la extracción en una lista de datos actualice esa lista. El control ListView
admite esta lista de fábrica. Para habilitar la funcionalidad de extracción a actualización, establezca IsPullToRefreshEnabled
en true
:
<ListView ...
IsPullToRefreshEnabled="true" />
El código de C# equivalente es el siguiente:
listView.IsPullToRefreshEnabled = true;
Aparece un spinner durante la actualización, que es negro de forma predeterminada. Sin embargo, el color de número se puede cambiar en iOS y Android estableciendo la propiedad RefreshControlColor
en un Color
:
<ListView ...
IsPullToRefreshEnabled="true"
RefreshControlColor="Red" />
El código de C# equivalente es el siguiente:
listView.RefreshControlColor = Color.Red;
Las capturas de pantalla siguientes muestran la extracción para actualizar a medida que el usuario extrae:
Las capturas de pantalla siguientes muestran la extracción para actualizar después de que el usuario haya liberado la extracción, con el spinner que se muestra mientras se actualiza el ListView
:
ListView
desencadena el evento Refreshing
para iniciar la actualización y la propiedad IsRefreshing
se establecerá en true
. Cualquier código necesario para actualizar el contenido del ListView
debe ejecutarse después por el controlador de eventos para el evento Refreshing
o por el método ejecutado por el RefreshCommand
. Una vez actualizado el ListView
, la propiedad IsRefreshing
debe establecerse en false
, o se debe llamar al método EndRefresh
para indicar que la actualización está completa.
Nota:
Al definir un RefreshCommand
, se puede especificar el método CanExecute
del comando para habilitar o deshabilitar el comando.
Detectar desplazamiento
ListView
define un evento de Scrolled
desencadenado para indicar que se produjo el desplazamiento. En el ejemplo de XAML siguiente se muestra ListView
, que establece un controlador para el evento Scrolled
:
<ListView Scrolled="OnListViewScrolled">
...
</ListView>
El código de C# equivalente es el siguiente:
ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;
En este ejemplo de código, el controlador de eventos OnListViewScrolled
se ejecuta cuando se desencadena el evento Scrolled
:
void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
Debug.WriteLine("ScrollX: " + e.ScrollX);
Debug.WriteLine("ScrollY: " + e.ScrollY);
}
El controlador de eventos OnListViewScrolled
genera los valores del objeto ScrolledEventArgs
que acompaña al evento.