[Xamarin.Forms] Nuevo CarouselView!

Introducción

Con el lanzamiento de Xamarin.Forms 4.3 nos llegan una gran variedad de novedades: CarouselView, RefreshView, HTML en Label, etc. Es un buen momento para profundizar en el uso de CarouselView.

Nuevo Carousel!

El CarouselView permite mostrar una colección donde se pueden desplazar los elementos haciendo deslizamientos (gestos de Swipe).

CarouselView está disponible en Xamarin. forms 4.3. Sin embargo, actualmente esta en fase experimental y solo se puede usar agregando la siguiente línea de código a la clase AppDelegate en iOS, o bien a la clase MainActivity en Android, antes de llamar a Forms.Init:

Forms.SetFlags("CarouselView_Experimental");

NOTA: El CarouselView esta disponible para Android, iOS y UWP.

Una parte muy interesante del nuevo CarouselView es que su implementación esta basada en CollectionView (se reutiliza una cantidad considerable de código). Sin embargo, los controles tienen casos de uso bastante diferentes. CollectionView se suele usar para mostrar un listado de datos, mientras que CarouselView se suele usar para resaltar información en una lista de longitud más limitada.

Comencemos viendo las propiedades fundamentales del control. El CarouselView obtiene su fuente de información utilizando la propiedad ItemsSource.

<CarouselView ItemsSource="{Binding Items}" />

La apariencia de cada elemento se puede definir utilizando la propiedad ItemTemplate:

<CarouselView ItemsSource="{Binding Items}">
     <CarouselView.ItemTemplate>
          <DataTemplate>
               <StackLayout>
                    <Frame>
                    ...
                    </Frame>
               </StackLayout>
          </DataTemplate>
     </CarouselView.ItemTemplate>
</CarouselView>

La propiedad CurrentItem, de tipo object, tiene asociado el elemento actual visible. Esta propiedad tiene un modo de enlace predeterminado de TwoWay y tiene un valor null cuando no hay datos. Por otro lado, también tenemos la propiedad Position, de tipo int, que es el índice del elemento actual.

Orientación

Llegamos a otra de las propiedades claves del control, ItemsLayout. Esta propiedad de tipo LinearItemsLayout, especifica el panel que se va a utilizar. Cuenta con varias propiedades que nos permiten modificar el comportamiento del mismo:

  • Orientation: Propiedad de tipo ItemsLayoutOrientation. Soporta layouts de forma horizontal o vertical.
  • SnapPointsAlignment: Especifica cómo se alinean los puntos de anclaje con los elementos (Start, Center, End).
  • SnapPointsType: Especifica el comportamiento de los puntos de anclaje al desplazarse (no anclar el elemento, etc).
  • ItemSpacing: Es el espacio entre cada elemento.
<CarouselView ItemsSource="{Binding Items}">
     <CarouselView.ItemsLayout>
          <LinearItemsLayout Orientation="Horizontal" />
     </CarouselView.ItemsLayout>
</CarouselView>

Sencillo, ¿verdad?.

Controlando el número de elementos visibles

El Carousel por defecto, muestra un elemento ocupando el ancho del control. Sin embargo, podemos modificar este comportamiento de varias formas.

Por un lado, contamos con la propiedad NumberOfSideItems, un entero que representa el número de elementos que se van a mostrar junto al elemento actual (por ejemplo, si indicamos 1 se mostrará un elemento a izquierda y otro a derecha del elemento actual).

<CarouselView ItemsSource="{Binding Items}"
     NumberOfSideItems="1">
</CarouselView>

Por otro lado, tenemos la propiedad PeekAreaInsets, en un valor de tipo Thickness que especifica la cantidad de espacio que puede ver de los elementos adyacentes. Es una opción ideal si se quiere mostrar de forma parcial un elemento para indicar al usuario que hay más contenido de una forma sencilla.

<CarouselView ItemsSource="{Binding Monkeys}"
     PeekAreaInsets="0,0,200,0">
</CarouselView>

EmptyView

EmptyView permite añadir una View a mostrar en caso de que el número de elementos enlazado sea cero o nulo.

Se soporta desde una sencilla cadena de texto:

<CarouselView ItemsSource="{Binding EmptyItems}"
EmptyView="No items." />

A una View tan compleja como sea necesario:

<CarouselView ItemsSource="{Binding Items}">
     <CarouselView.EmptyView>
          <StackLayout>
               <Label Text="No items."
                    FontAttributes="Bold" />
          </StackLayout>
     </CarouselView.EmptyView>
</CarouselView>

Desplazamiento

Poder desplazarnos entre elementos es una de las características del Carousel. Por lo tanto, tener el control sobre el desplazamiento es algo importante.

Podemos controlar si se puede hacer desplazamiento (Swipe) mediante la propiedad IsSwipeEnabled. También podemos saber cuando se hace drag con la propiedad IsDragging.

CarouselView cuenta con dos sobrecargas del método ScrollTo, usando índices u objetos para hacer scroll a una posición concreta:

carouselView.ScrollTo(3);

Eventos

Para detectar cuando se realiza desplazamiento, podemos usar el evento Scrolled:

carouselView.Scrolled += OnCarouselViewScrolled;

void OnCarouselViewScrolled(object sender, ItemsViewScrolledEventArgs e)
{
     Debug.WriteLine("HorizontalDelta: " + e.HorizontalDelta);
     Debug.WriteLine("VerticalDelta: " + e.VerticalDelta);
     Debug.WriteLine("HorizontalOffset: " + e.HorizontalOffset);
     Debug.WriteLine("VerticalOffset: " + e.VerticalOffset);
     Debug.WriteLine("FirstVisibleItemIndex: " + e.FirstVisibleItemIndex);
     Debug.WriteLine("CenterItemIndex: " + e.CenterItemIndex);
     Debug.WriteLine("LastVisibleItemIndex: " + e.LastVisibleItemIndex);
}

Contamos con información relacionada con índices (elemento actual, anterior, etc.) y de offsets (distancia transladada).

Además de detectar el cambio de scroll (por ejemplo, para animar y hacer una transición entre elementos, algo que veremos en otro artículo), nos interesa saber cuando se cambia el elemento actual. Para ello, contamos con PositionChanged:

carouselView.PositionChanged += OnPositionChanged;

void OnPositionChanged(object sender, PositionChangedEventArgs e)
{
     int previousItemPosition = e.PreviousPosition;
     int currentItemPosition = e.CurrentPosition;
}

Por supuesto, contamos con más propiedades y eventos, pero en este artículo nos hemos centrado en los básicos o más usados.

Manos a la obra!

Tras repasar las propiedades y eventos principales del control, vamos a crear un pequeño ejemplo:

<CarouselView 
     CurrentItem="{Binding CurrentPost, Mode=TwoWay}"
     ItemsSource="{Binding Posts}"
     ItemTemplate="{StaticResource PostItemTemplate}">
     <CarouselView.PeekAreaInsets>
          <OnPlatform x:TypeArguments="Thickness">
               <On Platform="iOS" Value="0, 0, 200, 0" />
               <On Platform="Android" Value="0, 0, 600, 0" />
     </OnPlatform>
     </CarouselView.PeekAreaInsets>
     <CarouselView.ItemsLayout>
         <ListItemsLayout
              Orientation="Horizontal"
              SnapPointsType="Mandatory"
              SnapPointsAlignment="Start"
              ItemSpacing="12"/>
     </CarouselView.ItemsLayout>
</CarouselView>

Hemos realizado un ejemplo de una App de viajes. Mostraremos las últimas noticias destacadas usando el CarouselView combinando “cartas” con video, etc.

El resultado es el siguiente:

Ejemplo usando CarouselView

Vamos a repasar las claves del ejemplo. Para mostrar dos elementos completos y una parte del tercero, utilizamos la propiedad PeekAreaInsets. Otro propiedad con un uso interesante en el ejemplo es la propiedad CurrentItem. Al hacer scroll y cambiar el elemento actual, notificamos el cambio en la ViewModel que actualizará a su vez la URL del video a reproducir actualizando la reproducción de fondo.

Puedes encontrar el código en GitHub:

Ver GitHub

¿Qué te parece el CarouselView?. Recuerda, puedes dejar cualquier feedback en los comentarios de la entrada.

Más información

Un pensamiento en “[Xamarin.Forms] Nuevo CarouselView!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s