[Preview] Primer vistazo a Xamarin.Forms CollectionView

Introducción

Como parte de las novedades que llegan con Xamarin.Forms 4.0 se encuentra el nuevo control CollectionView.

Xamarin.Forms CollectionView

CollectionView llega con el objetivo de mejorar lo ofrecido por el control ListView hasta ahora:

  • Facilitar más opciones como listados horizontales o Grids.
  • Cubrir opciones muy solicitadas (vista para cuando no hay contenido, etc.).
  • Mejorar rendimiento.
  • Etc.

Primeros pasos

Para habilitar CollectionView es necesario utilizar un flag antes de inicializar Xamarin.Forms (recuerda, estamos ante una preview).

global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");

Layout básico

Podemos conseguir el mismo Layout de un ListView de forma sencilla. Como ventaja, con CollectionView no es necesario utilizar celdas, es decir, no usaremos ViewCell. Esto tiene un impacto en el rendimiento, sobretodo en Android, pero manteniendo la estructura y Layout del ListView.

<CollectionView 
     ItemsSource="{Binding Monkeys}">
     <CollectionView.ItemTemplate>
          <DataTemplate>
               <Grid 
                    HeightRequest="48">
                    <Label 
                         Text="{Binding Name}"
                         FontSize="18"
                         VerticalOptions="Center"/>
               </Grid>
          </DataTemplate>
     </CollectionView.ItemTemplate>
</CollectionView>

El resultado:

Layout básico

Fíjate que usamos un DataTemplate sin necesidad de ViewCell!.

Listas horizontales

Por defecto, el CollectionView utilizar un layout lineal. Esto quiere decir que se pueden hacer listas verticales pero…también horizontales!.

El control CollectionView cuenta con la propiedad ItemsLayout. Podemos establecer esta propiedad a una nueva instancia de GridItemsLayout que cuenta con una propiedad Orientation para definir la orientación.

<CollectionView.ItemsLayout>
     <GridItemsLayout
          Orientation="Horizontal" />
</CollectionView.ItemsLayout>

El resultado:

Listas horizontales

Carousel

Algo similar pero más complejo, un Carousel. Contar con un elemento scrollable pero navegando de elemento en elemento. Contamos con un control llamado CarouselView, un control nuevo basado en CollectionView, que podemos utilizar para conseguir el formato clásico de “carta” y paso de elemento a elemento:

<CarouselView 
     ItemsSource="{Binding Monkeys}">
     <CarouselView.ItemsLayout>
          <GridItemsLayout
               Orientation="Horizontal" 
               SnapPointsAlignment="Center" 
               SnapPointsType="Mandatory"/>
     </CarouselView.ItemsLayout>
</CarouselView>

El resultado:

Carousel

Una de las características más interesantes que tenemos disponible es la posibilidad de controlar el comportamiento y alineación de cada elemento al hacer el desplazamiento. Lo conseguimos con las propiedades SnapPointsType y SnapPointsAlignment.

Grid

Por defecto, CollectionView utiliza un layout lineal. Es decir, por defecto podemos hacer listas verticales u horizontales. Como ya vimos previamente, con la propiedad ItemsLayout podemos modificar el comportamiento del Layout.

<CollectionView.ItemsLayout>
     <GridItemsLayout
          Orientation="Vertical"
          Span="2"/>
</CollectionView.ItemsLayout>

Utilizando GridItemsLayout podemos controlar la orientación con la propiedad Orientation y con la propiedad Span el número de elementos por fila o columna.

Grid Layout

Vista cuando no hay contenido

¿Qué ocurre cuando ItemsSource no tiene elementos?. Probablemente, hasta ahora con el ListView has jugado con paneles y visibilidad para dar feedback al usuario ante esta situación. CollectionView viene a mejorar esto. Podemos utilizar la propiedad EmptyView para mostrar cualquier contenido en caso de tener elementos.

<CollectionView 
     ItemsSource="{Binding Monkeys}">
     <CollectionView.EmptyView>
          <Grid>
          <Label 
               Text="No items"
               HorizontalOptions="Center"
               VerticalOptions="Center"/>
          </Grid>
     </CollectionView.EmptyView>
</CollectionView>

El resultado:

Sin contenido

Sencillo, ¿verdad?.

Tienes el ejemplo disponible en GitHub:

Ver GitHub¿Qué te parece?, ¿qué te resulta más interesante?. Recuerda, puedes dejar comentarios en la entrada!.

Más información

Anuncios

[Preview] Primer vistazo a Xamarin.Forms Visual

Introducción

A la hora de desarrollar aplicaciones multiplataforma, buscamos llegar a diferentes plataformas cada una de ellas con sus propias guías de estilo, controles e idiosincrasia. Sin embargo, en ocasiones como desarrolladores móviles buscamos conseguir el mismo aspecto. Con Xamarin.Forms, a pesar de contar con una capa de abstracción en la capa de UI permitiendo definir la interfaz una única vez, creamos aplicaciones nativas. Es decir, utilizando Xamarin.Forms utilizamos los controles nativos de cada plataforma. Para conseguir un mismo aspecto necesitamos utilizar Custom Renderers o efectos en ocasiones.

Xamarin.Forms Visual

Con Xamarin.Forms 4.0-pre1 nos llega una nueva forma de indicar una forma de renderizar los controles nativos con Visual.

Cuando utilizamos Visual, se utiliza el renderizado personalizado en cada plataforma en lugar del renderizado predeterminado.

NOTA: Utilizando Visual seguimos utilizando controles 100% nativos.

Para establecer el uso de Visual, utilizaremos la propiedad Visual:

<ContentPage 
     Visual="Material">

</ContentPage>

La propiedad Visual esta disponible en la clase VisualElement. Cualquier elemento hijo de otro heredará el valor de la propiedad y modificará su forma de renderizar. Por este motivo, si establecemos Visual a nivel de ContentPage aseguramos que cualquier elemento de la página utilizará el nuevo sistema de renderizado.

NOTA: El valor de la propiedad Visual puede cambiar en tiempo de ejecución.

Nos llega esta funcionalidad en modo Preview con la apariencia basada en Material Design. Actualmente, en la versión 4.0-pre1 contamos con Material Design en Android e iOS para los siguientes controles:

  • Button
  • Entry
  • Frame
  • ProgressBar

Para utilizar Visual, por ahora (recuerda, estamos ante una Preview) es necesario añadir la siguiente línea:

Forms.SetFlags("Visual_Experimental");

Antes de llamar a Forms.Init. Además, en iOS, es necesario añadir el paquete NuGet Xamarin.iOS.MaterialComponents.

NOTA: Visual requiere API 29 para funcionar en Android.

Veamos un ejemplo:

<Grid
     BackgroundColor="DarkGray">
     <Frame 
          Style="{StaticResource SignInFrameStyle}">
          <StackLayout 
               Style="{StaticResource SignInPanelStyle}">
               <Label 
                    Text="Sign in"
                    Style="{StaticResource SignInTitleStyle}" />
               <Entry 
                    Placeholder="Username" />
               <Entry 
                    IsPassword="True"
                    Placeholder="Password" />
               <Button 
                    Text="Sign in" 
                    Style="{StaticResource SignInButtontyle}"/>
          </StackLayout>
     </Frame>
</Grid>

El resultado:

Tienes el ejemplo disponible en GitHub:

Ver GitHub

Más información

[Material] Monkey Conf 2018

El evento

En España tenemos una comunidad .NET activa y diversa. Gracias a ello tenemos eventos anuales de gran calidad relacionadas con Azure, SQL Server e incluso AI. Sin embargo, a pesar de contar con una enorme variedad de desarrolladores Xamarin realizando grandes cosas, nos faltaba un evento donde reunirnos todos. Para solventar este problema, nace Monkey Conf 2018.

Con una enorme facilidad, hablando con compañeros y amigos el evento empezó a tomar forma muy rápidamente. Muchos quisieron patrocinar el evento (gracias a ellos pudimos tener desayuno, almuerzo, camisetas o regalar licencias), otros querían participar con sesiones, e incluso algunos se ofrecieron para ayudar con la organización, etc.

Gracias a todos ellos, el pasado 01 de Diciembre, celebramos la Monkey Conf 2018. A continuación, una pequeña galería del evento:

Fue un día lleno de sesiones técnicas de calidad. Es increíble ver sesiones donde se dan consejos de distribución y venta de apps basadas en la experiencia real con consejos de arquitectura de código. Esto demuestra el nivel y madurez de la comunidad Xamarin. Desde la recepción hasta el final, donde no podía faltar “el preguntón” (gracias a MFractor, LiveXaml y Steema por facilitarnos licencias) el día fluyo de forma natural, sin ningun problema de ningún tipo. Muchas gracias a sponsors, asistentes y ponentes por ello!.

Sponsors, gracias!

Quiero destacar un momento, inesperado y emotivo. Entre los ponentes decidieron darme una sorpresa y me regalaron un teclado Corsair mecánico que ya estoy utilizando. Como se suele decir, chicos, no teníais porque, pero muy agradecido!.

Muchas gracias!

El material

Vamos al material. Participé en el evento con una sesión acerca de Xamarin.Forms Shell.

Aprendimos en que consiste, vimos como funciona Visual para conseguir la misma apariencia en Android e iOS y también conocimos CollectionView.

Por la tarde participé en un taller de desarrollo de aplicaciones Xamarin.

Realizamos una divertida aplicación con Xamarin.Forms y Custom Vision para determinar si una foto tomada desde la aplicación, es un HotDot o no (si, la idea viene de la serie Silicon Valley de HBO).

En cuanto al material (ejemplos, demos), se esta recopilando todo en un repositorio disponible en GitHub:

Ver GitHub

Más información

[Offtopic] Nuevos retos profesionales!

Nuevos retos

No suelo compartir nada que no sea directa o indirectamente técnico mediante el Blog. Pero esta ocasión creo que merece que la comparta con todos vosotros. En ocasiones, cuando menos te lo esperas, se te cruza una oportunidad en tu camino que no puedes dejar pasar. Estamos ante esa situación. Un reto grande, con un gran equipo detrás,  etc. Por ello, he tomado la decisión de cambiar de empresa. Tras un tiempo en Plain Concepts donde sin duda he aprendido y crecido en muchos sentidos, donde dejo a grandes profesionales y amigos, comenzaré con tremenda ilusión y muchas ganas un nuevo camino en Microsoft.

Quiero dar las gracias a Plain Concepts en general, trabajar en un lugar así es un privilegio por el equipo técnico y por el nivel humano. Sentirme entre amigos y arropado en todo momento es sin duda, especial. Muchas gracias!.

El conocer al equipo humano que me rodeará, el reto y las posibilidades de seguir aprendiendo han provocado mi actual decisión. Espero estar a la altura de las circustancias. Sin duda, daré el 101%.

¿Qué ocurrirá con el blog?

Nada. Al menos nada diferente. Todo seguirá como hasta ahora. Publicaré artículos de samples, addins y herramientas que vaya realizando además de novedades en Xamarin en general.

[Tips and Tricks] Utilizando Code Snippets en Visual Studio para macOS

Introducción

Como desarrolladores, a la hora de programar en determinadas ocasiones escribimos código repetitivo. Si nos centramos en el desarrollo de aplicaciones Xamarin.Forms desde Visual Studio para macOS, por ejemplo; a la hora de definir ViewModels tenemos código repetitivo como la definición de propiedades o comandos.

public string Name
{
     get => _name;
     set => SetProperty(ref _name, value);
}

public string SurName
{
     get => _surname;
     set => SetProperty(ref _surname, value);
}

¿Y si tenemos una forma de mejorar nuestra productividad a la hora de escribir código repetitivo / similar?

Creando Code Snippets

En Visual Studio para macOS cuenta con una solución para este problema, code snippets.

¿Qué es un code snippet?

Un snippet de código es una pieza de texto guardada como plantilla, reutilizable y que puede contar con argumentos reemplazables por valores al ser utilizados.

Veamos un ejemplo:

private $type$ $field$;

public $type$ $property$
{
     get => $field$;
     set => SetProperty(ref $field$, value);
}

Cada parte del código rodeada por $, representa un argumento que se puede reemplazar por un valor. En el ejemplo anterior usamos tres argumentos para controlar el tipo de la propiedad, el nombre de la variable y el nombre de la propiedad.

Bien, pero…¿y cómo creamos code snnipets?.

Accedemos a la ventana de Preferencias de Visual Studio para macOS. Y desde aquí al editor de Code Snippets.

Code Snippets

Debemos pulsar sobre el botón Add para añadir un nuevo snippet.

Nuevo Snippet

Tenemos que rellenar:

  • Shortcut: Una de las partes más importantes. Es el atajo que utilizaremos con IntelliSense para utilizar el snippet.
  • Group: Representa la carpeta donde se guardará el snippet dentro del panel de preferencias de Code Snippet.
  • Description: La descripción del snippet. Esta descripción aparecerá en el tooltip al utilizarlo.
  • Mime: El mime-type del lenguaje de código que el code snippet soporta.
  • Template Text: El contenido del snippet de código.

Nuestro snippet!

Utilizando Code Snippets

Llega el momento que esperábamos!. Escribimos el valor del Shortcut de nuestro snippet.

Comenzamos a usar el Snippet

Pulsamos el tabulador y…

Voila!. Basta con definir el tipo y nombre de variable y propiedad para tener una propiedad pública completa en la ViewModel.

Basta ya con definir tipo y nombres

Los Code Snippets son fáciles de crear y usar pero ayudan a acelerar la creación de código aumentando nuestra productivad.

¿Usabas los snippets?. Recuerda, puedes dejar cualquier duda en los comentarios del artículo.

Más información

Recopilación de addins y herramientas para Visual Studio para macOS

Introducción

Visual Studio para macOS va mejorando versión tras versión, pero hay funcionalidad cubierta o mejorada por la comunidad y terceros. Hay ejemplos destacados como LiveXAML o MFractor. Sin embargo, ¿conoces más addins?, ¿cuáles?.

Recopilatorio de addins y herramientas para Visual Studio para macOS

De igual forma que con Xamarin.Forms, tras ir anotando addins y herramientas decidí moverlas a repositorio público, he creado un repositorio público donde agrupar todo el conjunto de addins, herramientas y cualquier tipo de documentación o elemento relacionado con Visual Studio para macOS.

Tienes el repositorio disponible en GitHub:

Ver GitHub¿Qué te parece?, ¿utilizas addins que no estan en la lista?. Se aceptan PRs, hagamos entre todos la lista lo más completa posible!

Más información

Xamarin.Forms Compiled Bindings

Introducción

El sistema de enlace a datos (Bindings) incluido en Xamarin.Forms es una de las piezas fundamentales a la hora de trabajar con la UI y la arquitectura de la App. Sin embargo, el sistema de enlace a datos cuenta con algunos problemas:

  • Los Bindinds se resuelven en tiempo de ejecución usando reflexión con un coste (rendimiento) variado dependiendo de la plataforma donde se ejecute el código.
  • No hay validación de expresiones de enlace a datos en tiempo de compilación ya que se resuelven en runtime. Esto quiere decir que, errores de bindings no son detectados hasta que la aplicación se esta ejecutando y ver que no se comporta como se espera, etc.

Utilizando Bindings compilados

Los bindings compilados están disponibles en Xamarin.Forms desde hace un tiempo. Entonces…¿por qué hablamos de ellos de nuevo?. En Xamarin.Forms 3.3 se soportan más escenarios para los bindings compilados.

El proceso para utilizar bindings compilados comienza por utilizar compilación de XAML:

[assembly: XamlCompilation (XamlCompilationOptions.Compile)]

A continuación, utilizamos el atributo x:DataType disponible en cada elemento de tipo VisualElement que afectará al elemento y todos sus hijos:

<StackLayout
     x:DataType="viewModels:MainViewModel">
     <StackLayout.BindingContext>
          <viewModels:MainViewModel />
     </StackLayout.BindingContext>
     <Label
          Text="{Binding Value1}"/>
     <Label
          Text="{Binding Value2}" />
     <Label
          Text="{Binding Value3}" />
</StackLayout>

NOTA: Es recomendable establecer el atributo x: DataType en el mismo nivel de la jerarquía de elementos visuales en que se establece BindingContext.

Utilizando compilación XAML, las expresiones de enlace a datos no válidas se informarán como errores de compilación. Sin embargo, el compilador XAML solo informará un error de compilación para la primera expresión de enlace no válida que encuentre.

Mezclando Bindings compilados con clásicos

Las expresiones de enlace a datos solo se compilan para los elementos visuales de la jerarquía visual donde se define el atributo x:DataType. De igual forma, cualquier vista sin el atributo x:DataType utilizará enlaces a datos clásicos. Las expresiones de enlace a datos solo se compilan para la jerarquía de vistas en la que se define el atributo x: DataType.

Veamos un ejemplo donde combinar bindings compilados y no clásicos:

<StackLayout
     x:DataType="viewModels:MainViewModel">
     <StackLayout.BindingContext>
          <viewModels:MainViewModel />
     </StackLayout.BindingContext>
     <Label
          Text="{Binding Value1}"/>
     <Label
          Text="{Binding Value2}" />
     <Label
          Text="{Binding Value3}" />
     <StackLayout
          x:DataType="{x:Null}">
          <Label
               Text="{Binding Value4}" />
          <Label
               Text="{Binding Value5}" />
     </StackLayout>
</StackLayout>

Rendimiento

Los bindings compilados mejoran el rendimiento:

  • Un binding con soporte a notificación de cambios (OneWay, OneWayToSource, TwoWay) se resuelve unas 8 veces más rápido que un binding clásico.
  • Un binding compilado sin soporte a notificación de cambios (OnwTime) se revuelve 20 veces más rápido.
  • Establecer un BindingContext con bindings compilados es entorno a 5 veces más rápido que con bindings clásicos.

Entonces, ¿ofrecen mejor rendimiento los bindings compilados?

Si!. Los bindings clásicos usan reflexión. Los bindings compilados eliminan el uso de reflexión y pasan a usar una Func para obtener datos, Action para establecer datos y una lista de handlers para gestionar el cambio de propiedades.

La mejora de rendimiento depende principalmente de la plataforma, versión del sistema operativo, dispositivo, etc. Sin embargo, como podemos ver en los números anteriores, los bindings compilados son 5-20 veces más rápidos.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Más información

[Material] .Net Conf Sevilla 2018

El evento

El pasado 24 de Octubre, teníamos en CartujaDotNet un evento bastante completo donde revisamos las últimas novedades disponibles en Xamarin, C#, .NET Core, ML.Net, Azure, Azure DevOps, etc.

El material

A continuación puedes encontrar la presentación utilizada en el evento:

Una tarde de repaso de una gran variedad de tecnologías, con preguntas interesantes y algo de netwotking asi que, ¿cuándo repetimos?.

Más información

[Evento] Monkey Conf 2018

El evento

Llega el evento técnico Xamarin que estabas esperando, Monkey Conf!.

Monkey Conf 2018

Monkey Conf será un evento gratuito, en el que trataremos temas relacionados con desarrollo móvil, Xamarin, Xamarin.Forms, App Center, testing y más…

La fecha

Será el próximo Sábado, 01 de Diciembre de 09:30h a 18:30h (GMT+1). Tendremos dos tracks en paralelo con diferentes sesiones técnicas de 50 minutos de duración cada una. Además contaremos con regalos y sorpresas!.

¿Te apuntas?

NOTA: Las entradas del evento son gratuitas pero limitadas!

El lugar

El evento se celebrará en Liferay. Dirección detallada:

Paseo de la Castellana, 280, 28046 Madrid, Madrid

Liferay

Call 4 Papers

¿Has desarrollado una aplicación con Xamarin?, ¿quieres hablar acerca de como usas App Center?, ¿revisar las próximas novedades de Xamarin.Forms?, ¿un taller?. El C4P del evento está abierto y estoy seguro que puedes hablar sobre algun tema que interese y ayude al resto!

Más información

[Xamarin.Forms] Utilizando TitleView

Introducción

Necesitar personalizar la barra superior de la aplicación añadiendo un logo, o un texto personalizado (utilizando una fuente específica, múltiples líneas, etc.) es bastante habitual. Hasta ahora, en Xamarin.Forms era algo posible pero…utilizando un Custom Renderer. Es un punto positivo de Xamarin.Forms, poder crear un Custom Renderer para acceder a características y elementos específicos de cada plataforma. Sin embargo, añade la necesidad de añadir más código (por plataforma) para conseguir un resultado.

Sin embargo, con la llegada de Xamarin.Forms 3.2 nos llega TitleView, una nueva opción para personalizar la barra superior sin necesidad de llegar a necesitar código específico por plataforma.

TitleView

TitleView es parte de NavigationPage, donde se muestra el contenido del título de una ContentPage.

Cabecera personalizada

Comenzamos por un ejemplo sencillo. Vamos a personalizar la cabecera con un icono y título:

<NavigationPage.TitleView>
     <StackLayout
          Orientation="Horizontal"
          VerticalOptions="Center"
          Spacing="10">
          <Image
               Source="Icon.png"
               Aspect="AspectFit" />
          <Label
               Text="TitleView"
               FontSize="18"
               TextColor="White"
               VerticalTextAlignment="Center" />
     </StackLayout>
</NavigationPage.TitleView>

Podemos añadir el contenido deseado tal y como haríamos en el contenido de una página.

El resultado:

Cabecera personalizada!

Comandos

Podemos utilizar los eventos, comandos e incluso GestureRecognizers en los elementos de la cabecera:

<NavigationPage.TitleView>
     <StackLayout
          Orientation="Horizontal"
          VerticalOptions="Center"
          Spacing="10">
          <Image
               Source="Icon.png"
               Aspect="AspectFit">
               <Image.GestureRecognizers>
                    <TapGestureRecognizer
                         Tapped="OnHeaderIconTapped"/>
               </Image.GestureRecognizers>
          </Image>
          <Label
               Text="TitleView"
               FontSize="18"
               TextColor="White"
               VerticalTextAlignment="Center" />
     </StackLayout>
</NavigationPage.TitleView>

En este sencillo, ejemplo, mostramos un dialogo al pulsar sobre el logo de la cabecera:

Gestos

Barra de búsqueda

Pasemos a un ejemplo más complejo y típico. Vamos a añadir una barra de búsqueda:

<NavigationPage.TitleView>
     <Frame
          CornerRadius="{OnPlatform 12, UWP=1}"
          BackgroundColor="{OnPlatform Transparent, Android={StaticResource WhiteColor}}"
          HasShadow="False"
          IsClippedToBounds="True"
          Padding="0">
          <Frame.Content>
               <SearchBar
                    x:Name="SearchBar"
                    Placeholder="Search movie..."
                    HorizontalOptions="FillAndExpand"
                    SearchCommand="{Binding SearchCommand}"
                    SearchCommandParameter="{Binding Text, Source={x:Reference SearchBar}}">
                    <SearchBar.Behaviors>
                         <behaviors:SearchTextChangedBehavior />
                    </SearchBar.Behaviors>
               </SearchBar>
          </Frame.Content>
     </Frame>
</NavigationPage.TitleView>

Mostramos un listado de peliculas de modo que, cada vez que cambia el texto de la barra de búsqueda, se actualiza el contenido de la página con el listado de películas filtrado.

El resultado:

Búsqueda

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Limitaciones o problemas conocidos actuales

Entre el listado de limitaciones actuales encontramos:

  • SearchBar debe ser contenido en un panel con HorizontalOptions=LayoutOptions.Fill y VerticalOptions=LayoutOptions.Fill, o bien, utilizar WidthRequest y HeightRequest específicos para que todo se vea correctamente en iOS.
  • TitleView no es compatible con Android FormsApplicationActivity.
  • El contenido no puede ser más grande que el tamaño predeterminado de la barra de navegación en iOS/UWP. En caso de intentarlo, habrá recorte de forma automática.
  • Ya contábamos con las propiedades BackTitle, Title, TitleIcon y ahora con TitleView ocupando el mismo espacio en la barra de navegación, puede que haya conflictos y espacio limitado para admitir todas estas propiedades al mismo tiempo. Esto variará según la plataforma y el tamaño de la pantalla.

Más información