[Xamarin.Forms] Novedades utilizando Resource Dictionaries

Resource Dictionaries

En toda aplicación móvil la apariencia visual es vital. Cada vez es mayor el esfuerzo depositado a la hora de crear aplicaciones atractivas a la par que intuitivas y en muchos casos conseguir una imagen única que diferencia a la Aplicación del resto es prioritario. Por este motivo, debemos de contar con opciones sencillas de poder personalizar los distintos elementos que componen la interfaz.

Los estilos permitir definir múltiples propiedades visuales de elementos de la interfaz de forma reutilizable.

Los recursos XAML son objetos que podemos reutilizar más de una vez. Hablamos desde un sencillo color o tamaño de fuente, a el uso de estilos. Los diccionarios de recursos o ResourceDictionaries permiten definir una zona donde definir recursos.

Hasta ahora…

Podíamos definir diccionarios de recursos en archivos totalmente independientes. Hablamos de una clase derivada de ResourceDictionary, que consta de un par de archivos. Por un lado tenemos el archivo XAML donde se definen los recursos y por otro lado, la clase subyacente encarga de realizar InitializeComponent.

NOTA: Para crear un archivo de tipo ResourceDictionary, crea una ContentPage o ContentView y renombra la clase base de ContentPage o ContentView a ResourceDictionary.

Veamos un ejemplo.

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     x:Class="ResourceDictionaries.MyResourceDictionary">

     <Style x:Key="LabelStyle"
          TargetType="Label">
          <Setter Property="TextColor"
               Value="Red" />
          <Setter Property="FontSize"
               Value="24" />
</Style>

</ResourceDictionary>

NOTA: Fíjate que utilizamos x:Class para establecer la clase subyacente necesaria.

Para utilizar el diccionario de recursos, creamos una instancia:

<ContentPage.Resources>
     <local:MyResourceDictionary />
</ContentPage.Resources>

La forma anterior de añadir el diccionario de recursos a pesar de ser válida es muy limitada ya que sólo nos permite utilizar los recursos del diccionario instanciado. Podríamos necesitar utilizar mñas de un diccionario de recursos o añadir otros recursos.

Para solucionar este problema, tenemos disponible la posibilidad de utilizar diccionarios de recursos combinados.

<ContentPage.Resources>
     <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
               <local:MyResourceDictionary />
          </ResourceDictionary.MergedDictionaries>
     </ResourceDictionary>
</ContentPage.Resources>

Podemos combinar varias instancias de diccionarios de recursos en uno existente. Se puede realizar directamente desde XAML utilizando la propiedad MergedDictionaries.

Con la llegada de Xamarin.Forms 3.0

La combinación de ResourceDictionary se simplifica con la llegada de Xamarin.Forms 3.0. Por un lado, ya no es necesario utlizar las etiquetas MergedDictionaries ya que en su lugar, podemos agregar directamente otro ResourceDictionary utilizando la propiedad Source.

Además, Xamarin.Forms 3.0 crea automáticamente una instancia de ResourceDictionary por lo que ya no es necesario añadir estas etiquetas.

<ContentPage.Resources>
     <ResourceDictionary Source="MyResourceDictionary.xaml" />
</ContentPage.Resources>

Esta nueva sintaxis no crea una instancia del diccionario de recursos. Gracias a este cambio, ya no es necesario mantener la clase subyacente o code behind del diccionario de recursos (MyResourceDictionary.xaml.cs) por lo que podemos borrarlo además del atributo x:Class de la ráiz del diccionario.

Más simple y sencillo!

Puedes encontrar un ejemplo en GitHub:

Ver GitHub

Más información

Anuncios

[Material DotNet2018] Xamarin.Forms Everywhere

El evento

El pasado 29 de Mayo tenía lugar la DotNet2018. Un gran día repleto de sesiones técnicas cubriendo todo el espectro de tecnologías .NET, desde Xamarin, Azure, IoT, VR, etc.

Fue un día genial de grandes sesiones pero también de encontrarte con grandes amigos, desvirtualizar a nuevos amigos, networking, etc. Quisiera agradecer a todos los ponentes y asistentes por hacer posible el evento. Y por supuesto, mi enhorabuena a toda la organización por hacer que algo tan grande y complejo fluyese de forma tan natural y sencilla.

El material

He tenido en placer de poder participar en el evento con una sesión acerca de Xamarin.Forms y nuevas plataformas o posibilidades.

Comenzamos el evento revisando Xamarin.Forms en Linux:

Xamarin.Forms en Linux

Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHub

Continuamos viendo estado y opciones de Xamarin.Forms en WPF:

Xamarin.Forms WPF

Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHub

Y continuamos con nuevos backends de Xamarin.Forms, y en esta ocasión hablamos de Ooui de Frank Krueger.

Desde el navegador!

Repasamos estado, un poco de WebAssembly y continuamos. Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHubContinuamos viendo los primeros pasos del backend de Windows Forms y dimos paso a nuevas posibilidades.

Hablamos de wearables y Tizen.CircularUI, donde repasamos opciones principales, etc.

Posteriormente llegço el turno de IoT. Tras una breve introducción a Xamarin.IoT vimos como ya contamos con plantillas de proyectos e integración entre Xamarin.Forms (backend GTK#) con Xamarin.IoT.

Monitor de temperatura realizado con Xamarin.IoT y Xamarin.Forms

Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHub

Tras ver nuevas plataformas o dispositivos con IoT o Wearables, nos centramos en nuevas posibilidades en UI. Hicimos un repaso de:

  • VisualStateManager
  • FexLayout
  • SkiaSharp
  • Etc

En este punto, vimos como crear interfaces combinadas con elementos 3D con Wave Engine o como combinar ARCore con Xamarin.Forms creando Custom Renderers.

ARCore

Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHub

Completamos el evento utilizando Xamarin.Forms para crear la UI de addins para Visual Studio en Windows y macOS.

El ejemplo:

Ver GitHub

Hasta el año próximo!

Y ya tenemos evento confirmado para el próximo año!. Apunta la fecha, 23 de Mayo.

DotNet 2019!

Allí nos vemos!

Más información

[Xamarin.Forms] Aplicaciones con contenido 3D utilizando Wave Engine

Introducción

A la hora de desarrollar aplicaciones móviles, nos encontramos con una enorme variedad de requisitos a nivel visual y de contenido. En Xamarin.Forms gracias al avance en novedades (pestañas en la parte inferior, bordes redondeados, etc.) junto a SkiaSharp, estilos, efectos y Custom Renderers otorgan grandes opciones para desarrollar aplicaciones visualmente atractivas.

En determinadas ocasiones, la visualización e interacción con elementos 3D o cámaras en 360 grados por ejemplo, otorga una mejor experiencia en nuestras aplicaciones. Por ejemplo, la visualización de edificios y diferentes plantas o la previsulización de un coche que deseamos comprar. Para conseguir la visualización e integración con elementos 3D tenemos diferentes opciones como Urho o Wave Engine.

En este artículo, vamos a ver como integrar elementos 3D en una aplicación Xamarin.Forms utilizando Wave Engine.

Wave Engine

Wave Engine es un motor de videojuegos 2D y 3D multiplataforma, basado en componentes y totalmente gratuito (no hay licencias ni tampoco ningún tipo de royalty). Nos ofrece una API para trabajar con físicas, animaciones, sonido, etc. utilizando C# sin tener que profundizar a más bajo nivel y tener que trabajar con DirectX directamente.

Podemos desarrollar para Android, iOS, Linux, macOS, Windows, etc..

Creando la escena 3D

Vamos a realizar un ejemplo sencillo pero suficientemente interesante para conocer:

  • La creación de una escena 3D.
  • Integrar una escena 3D en Xamarin.Forms.
  • Interactuar desde una vista XAML de Xamarin.Forms con la escena 3D.

Crearemos una escena con un coche y podremos modificar el color del mismo desde un ListView de Xamarin.Forms.

¿Y de dónde obtenemos el modelo 3D?

Para este ejemplo, vamos a utilizar un modelo 3D totalmente gratuito de Sketchfab gracias a Karol Miklas.

Sketchfab

Tras descargar el modelo 3D, arrancamos el editor de Wave Engine.

Editor Wave Engine

NOTA: Puedes descargar Wave Engine desde este enlace.

Creamos nuevo proyecto, y arrastramos el modelo descargado a la carpeta Assets en el apartado Assets Details. Podemos hacer doble clic en el archivo fbx para asegurar que todo es correcto.

Cargar el modelo

Comenzamos a montar nuestra escena arrastrando el modelo que acabamos de previsualizar desde Assets Details a la Scene:

Creando la escena

Llegados a este punto, tenemos suficiente. Podemos mejorar la escena con pequeños cambios como:

  • Añadir entidad plano 3D para ele suelo.
  • Añadir una esfera en forma de cúpula, para añadir “límites” al escenario.
  • Añadir más luces a la añadida por defecto.
  • Etc.

Integrando la escena con proyecto Xamarin.Forms

De momento, tenemos un proyecto Windows (proyecto creado por defecto) con nuestra escena. Podemos lanzar y probar nuestro proyecto.

Ejemplo en Windows

Pero…¿y cómo llegamos a integrarlo todo en Xamarin.Forms?. Wave Engine es un motor multiplataforma. Se pueden crear proyectos para plataformas como Android, iOS, UWP, Linux o macOS. Entre las diferentes opciones, para Android, iOS y UWP hay proyectos con integración con Xamarin.Forms.

Desde el editor de Wave Engine, Edit > Project Properties…

Nuevo perfil

Podemos elegir entre diferentes plataformas, y en cada plataforma diferentes Launchers. En Android, iOS y UWP contamos con Launcher Xamarin.Forms.

Xamarin.Forms

Esto nos crea automáticamente un nuevo proyecto utilizando Xamarin.Forms.

Estructura del proyecto

Tenemos una proyecto Shared con toda la lógica compartida de Wave Engine (escenas, behaviors, componentes, etc.) y otro proyecto de igual tipo donde tenemos la aplicación Xamarin.Forms con las vistas, etc.

Al final, trabajamos con una aplicación Xamarin.Forms habitual donde la carga de la escena 3D se realiza vía Custom Renderer. Contamos con el siguiente control:

public class WaveEngineSurface : View, IViewController
{
     public static readonly BindableProperty GameProperty = BindableProperty.Create(
     propertyName: "Game",
     returnType: typeof(IGame),
     declaringType: typeof(WaveEngineSurface),
     defaultValue: null);

     public IGame Game
     {
          get { return (IGame)GetValue(GameProperty); }
          set { SetValue(GameProperty, value); }
     }
}

Desde una vista XAML:

<AbsoluteLayout>
     <controls:WaveEngineSurface x:Name="WaveEngineSurface"
          AbsoluteLayout.LayoutFlags="All"
          AbsoluteLayout.LayoutBounds="0, 0, 1, 1" />
</AbsoluteLayout>

Interacción con la escena 3D

En este ejemplo, vamos a utilizar SlideOverKit para añadir un menu lateral deslizante, donde mostrar un listado de colores. La idea es permitir cambiar el color de coche en 3D. Pero para conseguirlo, necesitaremos interaccionar con la escena 3D desde nuestra aplicación Xamarin.Forms, ¿cómo lo hacemos?.

Al seleccionar cualquir color, lanzamos un comando en la ViewModel:

public ICommand ColorTappedCommand => new Command<CustomColor>(ChooseColor);

private void ChooseColor(CustomColor color)
{
     // TODO:
}

Al crear el proyecto Xamarin.Forms desde el editor visual tenemos una clase llamada WaveEngineFacade. Desde esta clase tenemos la opción de acceder a la escena. Creamos un método llamado UpdateColor. En el método debemos acceder a la entidad del coche, en concreto a su material, y modificar el color.

¿Cómo sabemos cual es esa entidad?.

Desde el editor, vemos el desglose de entidades (piezas) que componen al coche. Seleccionamos la carrocería y elegimos la opción Copy EntityPath:

Copy EntityPath

public static void UpdateColor(CustomColor color)
{
     var entity = _scene.EntityManager.Find("car.Plane_036.Plane_041");
     var materialComponent = entity.FindComponent<MaterialComponent>();
     var hex = color.Hex;
     ((StandardMaterial)materialComponent.Material).DiffuseColor = FromHex(hex);
}

NOTA: En la variable _scene tenemos acceso a cualquier elemento de la escena (cámara, luces, entidades, etc.). Utilizamos un método Initialize lanzado en el arranque de la aplicación para establecer el valor de la variable.

Desde el comando sencillamente lanzamos nuestro método:

WaveEngineFacade.UpdateColor(color);

El resultado final:

El resultado

Puedes encontrar el ejemplo realizado en GitHub:

Ver GitHub

Más información

Primer vistazo a Xamarin Live Reload

Introducción

Xamarin.Forms es un toolkit que crea una abstracción sobre la interfaz de usuario de Android, iOS, Tize, WPF, macOS, Linux y Windows permitiendo desarrollarla una única vez con código C# o Extensible Application Markup Language (XAML).

A la hora de trabajar con la interfaz de usuario, tenemos grandes herramientas como IntelliSense en XAML, Previewer o Xamarin Live Player. Sin embargo, las dos últimas opciones no soportan todas las características que se pueden utilizar en una aplicación móvil lo que provoca errores al renderizar y previsualizar el contenido. Por este motivo, tenemos algunas grandes herramientas por parte de la comunidad Xamarin como Live XAML o Gorilla Player.

En este artículo, vamos a conocer Xamarin Live Reload, nueva herramienta oficial que nos permite ver cualquier cambio de XAML al vuelo.

Xamarin Live Reload

El objetivo principal de Xamarin Live Reload es permitir ver cualquier cambio relacionado con la interfaz de usuario de forma rápida y sencillo, soportando cambios al vuelo sin necesidad de compilar y desplegar. Cualquier cambio en XAML será reflejado de forma automática manteniendo los cambios.

La clave fundamental de esta nueva herramienta es que soporta cualquier librería, control de terceros además de Custom Renderers o efectos. A la hora de ver la previsualización, podemos utilizar emuladores o dispositivos físicos.

Instalación

Para poder instalar Live Reload necesitamos los siguientes requisitos:

Bastará con descargar e instalar la siguiente extensión:

Instalar Xamarin Live Reload

Instalamos…

Live Reload

Tras instalar la herramienta es hora de configurar nuestra App para utilizarla. Es tarea sencilla ya que solo tendremos que añadir el paquete NuGet Xamarin.LiveReload a nuestra librería .NET Standard 2.0.

Xamarin.LiveReload

NOTA: Es necesario utilizar .NET Standard para utilizar Live Reload en estos momentos.

Para completar la configuración y utilizar la herramienta en nuestra aplicación, en la clase App.xaml.cs debemos añadir:

 LiveReload.Init();

En el punto de entrada de la misma, es decir, en el constructor.

Todo preparado!

Utilizando la herramienta

Tras crear un proyecto Xamarin.Forms y lanzarlo en depuración en el emulador vemos lo siguiente:

Comenzamos a usar Live Reload

Visual Studio nos indica (parte superior) que Live Reload esta funcionando en un emulador de Android. A partir de este momento, cualquier cambio será aplicado:

Live Reload en acción!

A tener en cuenta…

  • Live Reload funciona con XAML. Cualquier cambio en C# requiere recompilación.
  • Se soportan las plataformas soportadas por Xamarin.Forms.
  • No se soportan (por ahora) estilos CSS.
  • Sólo funciona utilizando librerías .NET Standard.
  • Se puede utilizar en emuladores o dispositivos.
  • No hay límite en el número de dispositivos a utilizar.
  • Si no se cambia la configuración de Live Reload ni tampoco la máquina donde se compiló el código, no es necesario desplegar de nuevo. Basta con abror la aplicación previamente desplegada, conectar y continuar.

Más información

Probando nuevo IntelliSense Xamarin.Forms XAML de Visual Studio 2017 15.7

Introducción

Con la llegada de la última Preview de Visual Studio 2017, la versión 15.7, llegan grandes mejoras en la experiencia al editar XAML de Xamarin.Forms. Ahora el engine que gestiona IntelliSense de XAML de Xamarin.Forms pasa a ser el mismo que WPF o UWP. Hablamos de mejoras en autocompletado, sugerencias, extensiones de marcado o navegación entre diferente código.

En este artículo, vamos a realizar un rápido repaso por las mejoras principales.

NOTA: Recuerda, hablamos de una versión Preview de Visual Studio. Es posible contar con la versión Preview instalada junto a la versión estable aunque estas mejoras aún no estan disponibles en la versión estable.

Un repaso a las mejoras principales

Autocompletado

Comenzamos con la funcionalidad básica, el autocompletado. Esta versión mejora la búsqueda de coincidencias con lo escrito obteniendo resultados aun con valores no correctos, incompletos, o con minúsculas o mayúsculas.

Autocompletado

Se obtiene ayuda para completar tanto elementos visuales como paneles o controles, así como sus propiedades o eventos.

Extensiones de marcado

Las extensiones de marcado son una forma de obtener un valor que no sea específico de tipo primitivo o un objeto XAML. Mediante la apertura y cierre de llaves, se define en su interior lo que se conoce como extensión de marcado.

Otra necesidad muy habitual al trabajar con XAML dada la alta probabilidad de requerir hacer un enlace a datos o acceder a un recurso:

Extensiones de marcado

Tenemos autocompletado con extensiones de marcado como Binding, StaticResource o x:Static, pero también con aquellas personalizadas.

 

Namespaces

Ahora también tenemos sugerencias al trabajar con XML namespaces:

Namespaces

Sugerencias

También tendremos sugerencias, como al editar C# aparecerá la linterna, principalmente indicando que algo no es correcto para permitir corregir el problema. Renombrar, crear espacio de nombres, etc…

Sugerencias

Resolución de recursos

Los recursos definidos en la misma página son detectados por IntelliSense facilitando sugerencias:

Resolución de recursos

NOTA: De momento, no se detectan recursos a nivel de aplicación, solo a nivel de página.

Errores

Cualquier error de marcado se indicará subrayando en azul la línea problemática.

Errores

Sin duda un paso sólido y necesario adelante de una de las opciones más reclamadas. Aun hay posibilidad de mejora (recursos a nivel de aplicación, más opciones de autocompletado como con estilos, etc.) pero tras probar desde pequeños proyectos a algunos de mayor tamaño, la mejora es notoria. Y a ti, ¿que te parece?.

Más Información

[Evento SVQXDG] Primer vistazo a novedades de Xamarin.Forms 3.0

Xamarin.Forms 3.0

Recientemente hemos recibido la versión Xamarin.Forms 3.0 Pre-Release. Esta nueva versión llega con soporte a .NET Standard, multi-targeting (también a PCL), mejoras en rendimiento, corrección de errores así como nuevas características. Entre las características nuevas encontramos:

  • Nuevas plataformas soportadas como Linux (GTK) o versiones anteriores de Windows (WPF).
  • Visual State Manager.
  • FlexLayout.
  • Uso de CSS para manejar estilos.
  • Localización Right to Left.

El evento

Ante tal cantidad de novedades, ¿algo mejor que verlas todas en un evento?. En este evento vamos a realizar un repaso de cada novedad a base de demos.

El evento se celebrará en la ETS de Ingeniería Informática. Dirección detallada:

E.T.S. Ingeniería Informática – Universidad de Sevilla, Aula A2.14
Av. Reina Mercedes s/n
Sevilla Se 41012

La fecha

Será el próximo Martes, 10 de Abril de 19:00h a 20:30h (GMT+1).

¿Te apuntas?

Más información

[Xamarin.Forms] Creando un Walkthrough usando Lottie

Introducción

A la hora de desarrollar aplicaciones móviles nos encontramos con ciertas necesidades a cubrir. Una bastante habitual es la de ofrecer en una experiencia sencilla y fluida una breve explicación de la propia aplicación, su funcionalidad o características más importantes.

Walkthrough

Para evitar que el usuario acabe “saltando” (Skip) el tutorial, es necesario atraer su atención. En este artículo, vamos a crear un Walkthrough o tutorial donde vamos a utilizar Lottie, animaciones de diferente tipo para conseguir atraer la atención de usuario.

Creando el Carousel

Comenzamos por la parte fundamental, el Carousel. El Carousel es un control que contiene una colección de contenido permitiendo navegar entre el mismo realizando un gesto de deslizamiento lateral.

Entre las diferentes opciones que tenemos disponibles (recuerda que existe paquete oficial para obtener un Carousel) tenemos CarouselView de Alexander Reyes. Es una opción interesante al permitir trabajar con:

  • Indicadores de posición.
  • Orientación: Vertical o Horizontal.
  • Animaciones
  • Control sobre estado, posición, si se muestran flechas para la navegación o no, etc.

CarouselView.FormsPlugin

Para trabajar con este Carousel, tras añadir el paquete NuGet correspondiente, añadimos el siguiente namespace en XAML:

xmlns:carousel="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"

La definición básica del control es sencilla:

<carousel:CarouselViewControl />

Bien, en nuestro caso, cada paso del tutorial será una ContentView. Podemos gestionar la colección de diferentes formas, una sencilla:

_views = new View[]
{
     new BikingHardView(),
     new AcrobaticsView(),
     new SoExcitedView(),
     new BikingCoolView()
};

Y utilizando la propiedad ItemsSource (se puede utilizar un enlace a datos), establecemos la colección.

Carousel.ItemsSource = _views;

Tenemos lo básico. Continuamos!.

Lottie a escena!

Utilizando páginas estáticas, sin movimiento, podemos conseguir la atención del usuario con una buena combinación de uso de imágenes, fuentes y otros recursos visuales.

Con un poco de “acción” lo tenemos más sencillo. Tenemos la posibilidad de trabajar con Lottie desde Xamarin para Android, iOS, así como en UWP y en Xamarin.Forms gracias a la gran comunidad Xamarin.

¿Qué es Lottie?

Airbnb ha desarrollado una herramienta Open Source con la que facilitar la creación de animaciones móviles. Podemos utilizar animaciones potentes creadas con After Effects y utilizarlas desde nuestras aplicaciones móviles de forma sencilla.

Para trabajar con Lottie en Xamarin.Forms, comenzamos añadiendo un paquete NuGet:

Lottie Xamarin.Forms

Recuerda añadirlo en cada proyecto de plataforma además de en la librería .NET Standard.

Para completar el proceso de preparación de Lottie en nuestro proyecto Xamarin.Forms, necesitamos añadir la siguiente línea tras la inicialización de Xamarin.Forms en cada proyecto nativo:

AnimationViewRenderer.Init();

Todo listo!.

Para mostrar la animación necesitamos un elemento visual que nos permita además realizar una gestión de la misma. Este elemento visual es AnimationView.

Para utilizar AnimationView desde XAML necesitamos utilizar el siguiente espacio de nombres:

xmlns:lottie="clr-namespace:Lottie.Forms;assembly=Lottie.Forms"

La interfaz:

<forms:AnimationView
     Animation="bikingishard.json"
     AutoPlay="true"
     Loop="True"
     Speed="1"
     HorizontalOptions="FillAndExpand"
     VerticalOptions="FillAndExpand" />

Hasta este punto, de forma sencilla, conseguimos un resultado bastante atractivo.

Obtener recursos

Un gran fuente de animaciones es LottieFiles. Puedes encontrar una gran variedad de animaciones listas para utilizar con opciones de búsqueda, etc.

LottieFiles

NOTA: Si usas animaciones de LottieFiles, recuerda otorgar crédito a sus creadores.

Añadimos más animaciones

Podemos continuar mejorando todo. En cada paso del tutorial vamos a añadir información relevante en texto y otros elementos visuales. Vamos a necesitar saber cuando el usuario pasa de un paso a otro.

De forma sencilla, podemos crear una interfaz como la siguiente:

public interface IAnimatedView
{
     void StartAnimation();
}

De modo que, cada vez que el usuario cambie la ContentView seleccionada, si el paso hereda de nuestra interfaz, ejecutamos la implementación de la misma.

var currentView = _views[e.NewValue];

if (currentView is IAnimatedView animatedView)
{
     animatedView.StartAnimation();
}

¿Qué conseguimos con esto?

Vamos a añadir otra dependencia vía NuGet con la librería Xamanimation. Esta pequeña librería añade una gran variedad de animaciones predefinidas además de la posibilidad de crear Storyboards, lanzar animaciones desde XAML, etc.

NOTA: Xamanimation formará parte del bloque de animaciones del Toolkit de Xamarin.Forms.

Añadimos espacio de nombres en XAML:

xmlns:xamanimation="clr-namespace:Xamanimation;assembly=Xamanimation"

Y podemos definir una animación de la siguiente forma:

<xamanimation:StoryBoard
     x:Key="InfoPanelAnimation"
     Target="{x:Reference InfoPanel}">
     <xamanimation:FadeToAnimation
          Duration="50"
          Opacity="1" />
     <xamanimation:TranslateToAnimation
          TranslateY="0"
          Easing="CubicIn"
          Duration="100" />
</xamanimation:StoryBoard>

Esta animación, animará un elemento visual marcado con el nombre InfoPanel, primero la opacidad de su estado inicial, 0, es decir, no visible, a 1 además de realizar una trasladación en el eje Y.

Para lanzarla:

if (Resources["InfoPanelAnimation"] is StoryBoard animation)
{
     animation.Begin();
}

Sencillo, ¿verdad?.

De igual forma, aprovechamos algunas animaciones de la librería para animar el color de fondo al pasar de un paso a otro entre otros detalles.

El resultado:

El resultado

NOTA: Las animaciones de Lottie de este ejemplo corresponden a Yue XI de LottieFiles.

Tienes el código fuente del ejemplo disponible GitHub:

Ver GitHub

Más información

[Xamarin.Forms] Primer vistazo a VistualStateManager

Introducción

Una de las funcionalidades que estarán disponibles en próximas versiones de Xamarin.Forms y ya disponible en las Nightly es VisualStateManager.

NOTA: Puedes acceder a los paquetes Nightly de Xamarin.Forms en este enlace.

En este artículo, vamos a darle un primer vistazo a esta nueva característica.

VisualStateManager

VisualStateManager se utiliza para definir y gestionar diferentes estados entre elementos visuales de una página. En concreto, un VisualState es la colección de propiedades de un elemento visual que en conjunto definen el estado de un elemento visual.

Para entender como utilizar VisualStateManager de forma sencilla, vamos a crear un ejemplo habitual. A continuación, vamos a crear un sencillo formulario para asegurar que el usuario registra una contraseña de forma correcta, es decir, vamos a pedir introducir la misma hasta en dos ocasiones:

<StackLayout>
     <Label
          Text="Password" />
     <Entry
          x:Name="Password"
          IsPassword="True" />
     <Label
          Text="Repeat Password" />
     <Entry
          x:Name="RepeatPassword"
          IsPassword="True" />
</StackLayout>

Sencillo, ¿verdad?. Lo ideal sería trasmitir al usuario feedback visual directo ante la repetición de la contraseña en caso de error.

¿Cómo lo hacemos?

VisualStateGroups

Vamos a crear un estilo para cada donde pedimos la repetición de la contraseña:

<Style
     x:Key="RepeatPasswordStyle"
     TargetType="Entry">
     <Setter
          Property="VisualStateManager.VisualStateGroups">
          <VisualStateGroupList
               x:Name="CommonStates">
               <VisualStateGroup>
                    <VisualState
                         x:Name="Valid">
                         <VisualState.Setters>
                              <Setter
                                   Property="BackgroundColor"
                                   Value="White" />
                         </VisualState.Setters>
                    </VisualState>
                    <VisualState
                         x:Name="Invalid">
                         <VisualState.Setters>
                              <Setter
                                   Property="BackgroundColor"
                                   Value="Red" />
                         </VisualState.Setters>
                     </VisualState>
                </VisualStateGroup>
           </VisualStateGroupList>
      </Setter>
</Style>

Creamos dos VisualState o estados visuales. El primero de ellos lo utilizamos cuando la contraseña es correcta. En el segundo estado, que utilizaremos cuando la contraseña sea incorrecta (no coincide) vamos a modificar el color de fondo a rojo.

Aplicamos el estilo.

<Entry
     x:Name="RepeatPassword"
     IsPassword="True"
     Style="{StaticResource RepeatPasswordStyle}" />

Hasta este punto, nada tiene efecto alguno. Necesitamos alguna forma de poder gestionar cada estado definido.

Gestión de estados

Para poder gestionar el estado a utilizar, VisualStateManager cuenta con el método GoToState para permitir cambiar entre diferentes VisualStates.

¿Cómo validamos la contraseña y cambiamos entre estados?

Creamos un Behavior:

public class ConfirmPasswordBehavior : Behavior<Entry>
{
     public static readonly BindableProperty CompareToEntryProperty =
     BindableProperty.Create("CompareToEntry", typeof(Entry), typeof(ConfirmPasswordBehavior), null);

     public Entry CompareToEntry
     {
          get { return (Entry)GetValue (CompareToEntryProperty); }
          set { SetValue (CompareToEntryProperty, value); }
     }

     protected override void OnAttachedTo (Entry bindable)
     {
          bindable.TextChanged += HandleTextChanged;
          base.OnAttachedTo (bindable);
     }
     protected override void OnDetachingFrom (Entry bindable)
     {
          bindable.TextChanged -= HandleTextChanged;
          base.OnDetachingFrom (bindable);
     }

     void HandleTextChanged (object sender, TextChangedEventArgs e)
     {
          var password = CompareToEntry.Text;

          if (string.IsNullOrEmpty (password))
               return;

          var confirmPassword = e.NewTextValue;
          var isValid = password.Equals (confirmPassword);

          if (isValid) 
          {
               Xamarin.Forms.VisualStateManager.GoToState ((Entry)sender, "Valid");
          } 
          else 
          {
              Xamarin.Forms.VisualStateManager.GoToState ((Entry)sender, "Invalid");
          }
     }
}

Aplicamos el Behavior:

<Entry.Behaviors>
      <behaviors:ConfirmPasswordBehavior
           CompareToEntry="{Binding Source={x:Reference Password}}" />
</Entry.Behaviors>

El resultado:

VisualStateManager

Según vamos escribiendo salta el evento TextChanged del Behavior y en el mismo, validamos si la contraseña es igual a la anterior. En este momento, utilizamos el método GoToState de VisualStateManager para cambiar de un estado a otro según el caso.

Tienes el código fuente del Toolkit disponible GitHub:

Ver GitHubEstamos ante una funcionalidad muy solicitada que añade bastante potencial para la gestión de estados ante la interacción de la aplicación. ¿Qué te parece a ti?. Recuerda, cualquier duda o comentario puedes añadirla a los comentarios de la entrada.

Más información

[Xamarin.Forms] Primer vistazo a FlexLayout

Introducción

Una de las grandes nuevas características que tendremos en Xamarin.Forms, ya disponible en paquetes Nightly, es FlexLayout.

En este artículo, vamos a realizar una introducción a este nuevo Layout, sus opciones y características principales.

Layouts de Xamarin.Forms

En Xamarin.Forms contamos con diferentes Layouts que nos permiten organizar y posicionar los diferentes elementos visuales que componen la interfaz de usuario.

Las clases Layout y Layout<T> en Xamarin.Forms son tipos especiales de Views que actúan como contenedores de otras Views o Layouts.

Layouts en Xamarin.Forms

¿Qué es FlexLayout?

Al trabajar con CSS en desarrollo web, para adoptar una sintaxis limpia para crear diseños adaptativos llegó Flexbox.

Flexbox proporciona una forma eficiente de distribuir, alinear y gestionar el espacio entre elementos incluso cuando el tamaño de la ventana o de cada elemento es dinámico o desconocido.

Basados en esta opción, contamos con un nuevo Layout llamado FlexLayout con gran cantidad de opciones para la gestión de la distribución y tamaño de elementos.

¿Por dónde empezamos?

Probablente sea tu primera pregunta. Comenzamos creando un nuevo proyecto Xamarin.Forms.

Tras crear el proyecto, actualizamos el paquete a la versión Nightly de Xamarin.Forms:

Xamarin.Forms Nightly

NOTA: Puedes ver como acceder a versiones Nightly de Xamarin.Forms en este enlace.

Basta con añadir en la página:

<FlexLayout>
</FlexLayout>

Para comenzar a trabajar con FlexLayout.

FlexLayout, propiedades

El comportamiento del Layout es diferente en base a sus propiedades. A continuación, vamos a revisar las propiedades fundamentales.

Direction

La propiedad Direction controla la dirección de los elementos. Los valores posible son:

  • Row
  • Column
  • RowReverse
  • ColumnReverse

Simplificando, esta propiedad permite definir como se distribuyen los elementos que contiene. Puede ser de forma horizontal, vertical o de forma invertida en ambas direcciones. La dirección predeterminada es horizontal, de izquierda a derecha.

NOTA: En el “mundo flexible” no se usa “horizontal” o “vertical” si no eje principal (main-axis) y eje transversal (cross-axis).

Aunque no se establezca de forma explícita, FlexLayout tiene como valor predeterminado Row.

Wrap

Contamos con los siguientes valores:

  • Wrap
  • NoWrap
  • Reverse

Pero…¿para qué lo usamos?.

Para entender correctamente esta propiedad vamos a crear un sencillo ejemplo. Dentro de un FlexLayout añadimos elementos:

Comenzando el ejemplo

Son textos de 24px de ancho. Por defecto, como hemos visto anteriormente se organizarán en formato de Row de izquierda a derecha.

Bien, vamos a duplicar los elementos. ¿Qué va a ocurrir?, ¿se salen elementos de pantalla?, ¿se ajusta el tamaño de todo?, ¿se dividen elementos a una nueva línea?.

Duplicamos elementos

Nada como probar, para tener la respuesta. El contenedor se adapta para poder contenedor todos los elementos hijos. Este es el comportamiento por defecto. Es decir, la propiedad Wrap tiene como valor predeterminado NoWrap.

Podemos modificar el comportamiento de forma sencilla:

Wrap

JustifyContent

Si hasta ahora piensas que todo tiene buena pinta, esta propiedad te va a gustar. Cuenta con las siguientes opciones:

  • Start
  • Center
  • End
  • SpaceBetween
  • SpaceAround
  • SpaceEvenly

Esta propiedad te puede recordar a la alineación de texto. Define como se organizan los elementos en el eje principal. El valor por defecto es Start. Con este valor los elementos se agrupan al inicio del eje principal.

Start

Por el contrario, la opción End agrupa los elementos al final del eje principal:

End

Centrados:

Center

La opción SpaceBetween mantiene el mismo espacio entre cada elemento:

SpaceBetween

SpaceAround, es similar a la opción anterior, los elementos se distribuyen uniformemente manteniendo además el mismo espacio alrededor (en ambos lados). Nota que el primer elemento tendrá una unidad de espacio con respecto al borde del contenedor, pero dos unidades con respecto al siguiente elemento (el siguiente elemento cuenta con su propio espacio).

SpaceAround

Por último, contamos con SpaceEvenly donde los elementos se distribuyen manteniendo el mismo espacio entre elementos y los bordes.

SpaceEvenly

AlignItems

Esta propiedad es similar a la anterior por lo que es rápida de asimilar. Los posibles valores son:

  • Start
  • Center
  • End
  • Stretch

Define el comportamiento predeterminado de cómo se colocan los elementos a lo largo del eje transversal (cross-axis).

El valor predeterminado es Stretch que se encargará de “estirar” los elementos para que rellenen toda la altura del contenedor. El resto de opciones hacen justo lo que imaginas, agrupan los elementos al inicio, centro o final del contenedor.

AlignContent

¿Recuerdas lo que pasaba al añadir más elementos al probar la propiedad relacionada con Wrap?. Utilizando Wrap tenemos un contenedor flexible multilínea.

Esta propiedad permite controlar la alineación de los elementos haciendo Wrapping. Nos permite controlar el espacio adicional en el eje transversal.

NOTA: Esta propuedad no tiene efcto cuando solo hay una línea de elementos.

Los valores posibles son:

  • Start
  • Center
  • End
  • Stretch
  • SpaceBetween
  • SpaceAround
  • SpaceEvenly

Como en AlignItems el valor por defecto es Stretch. Con este valor, los elementos se “estiran” para adaptarse al espacio disponible a lo largo del eje transversal.

Hemos visto anteriormente el resto de propiedades, sin embargo, hay en esta ocasión ligeras diferencias.

El valor Start alinea los elementos del contenedot al inicio del eje transversal. Recuerda que el eje transversal tiene como orden predeterminado de arriba hacia abajo. Por lo tanto, el valor End los coloca en la parte inferior (abajo) y Center en el centro.

Propiedades de cada elemento

Además de poder cambiar el comportamiento del Layout gracias a sus propiedades principales, podemos adaptar diferentes opciones utilizando propiedades de cada elemento.

FlexLayout.Grow

La gran aportación de FlexLayout es permitir que sus elementos sean “flexibles”. Esta propiedad nos permite tener aún más control en este sentido. El valor de la propiedad puede ser desde cero a cualquier valor numérico positivo. Vamos a ver en que consiste.

Por defecto, el valor de la propiedad es 0. Este valor hace que el elemento no crezca para ajustarse al espacio disponible. Podríamos decir que es como un “interruptor apagado”. Si tenemos en un contenedor un elemento, y establecemos el valor a 1, el elemento pasa a ocupar todo el espacio.

Básicamente, esta propiedad define la capacidad de un elemento para crecer si es necesario. Acepta un valor sin unidades que sirve como una proporción. Indica qué cantidad de espacio disponible dentro del contenedor flexible debe ocupar el elemento.

Si todos los elementotienen un crecimiento flexible establecido en 1, el espacio restante en el contenedor se distribuirá por igual a todos los hijos. Si uno de los hijostiene un valor de 2, el espacio restante ocuparía el doble de espacio que los demás (o lo intentará, al menos).

FlexLayout.Basis

Esta propiedad define el tamaño predeterminado de un elemento antes que se distribuya el espacio restante disponible. Puede ser una proporción, por ejemplo un porcentaje (5%, 25%, etc.). También se pueden utilizar algunas palabras reversadas como Auto.

En combinación con FlexLayout.Grow permite un control bastante completo sobre el tamaño de cada elemento hijo del contenedor.

Conclusiones

No es extraño encontrar la necesidad de gestionar Wrapping de elementos, elementos con diferentes espacios de forma dinámica, etc. La llegada de un nuevo Layout basado en algo conocido como Flexbox y que aporte la posibilidad de gestionar Layouts flexibles de forma sencilla es importante.

FlexLayout

Tienes un ejemplo de FlexLayout disponible en GitHub:

Ver GitHub¿Qué te parece esta nueva opción?. Recuerda, cualquier duda o pregunta es bienvenida en los comentarios de la entrada.

Más información

Xamarin.Forms en el navegador y WebAssembly

Introducción

Xamarin.Forms en la web. XAML en la web. Dependiendo de con quien hables es una idea que trae malos recuerdos y piensa en algo horrible o piensa que es genial aprovechar la expansión de Xamarin.Forms, llegar a la web y aprovechar para reutilizar herramientas, código, etc.

En cualquier caso, en este artículo, vamos a conocer Xamarin.Forms en la web, a definir estado y posibilidades así como hablar un poco de futuro.

Xamarin.Forms Everywhere!

Xamarin.Forms añade una capa de abstracción en la capa de UI permitiendo definir la misma una única vez (con XAML o C#) para todas las plataformas. La clave es que al ejecutar en cada plataforma, cada abstracción se convierte a un elemento nativo. Las diferentes plataformas soportadas por Xamarin.Forms reciben el nombre de backends y…cada vez tenemos más!. Actualmente hay backends para Android, iOS, GTK, macOS, WPF, UWP, Tizen y web.

Hablando del backend para web de Xamarin.Forms debemos realizar una especial mención a Frank Krueger, gran desarrollador con grandes aplicaciones y herramientas. En este caso, Frank también es el encargado de crear Ooui.

Ooui es una pequeña librería Open Source multiplataforma para simplificar el desarrollo web. Entre las diferentes opciones, Ooui cuenta con renderers Xamarin.Forms para permitir utilizar XAML y acabar teniendo elementos HTML corriendo en un navegador.

¿Cómo funciona?

Estamos hablando de una web, por lo tanto, tiene que haber un servidor que brinde el contenido. Cuando el usuario realiza una solicitud a una URL determinada, se sirve una página que mantiene una conexión con servidor utilizando Web Sockets. El servidor mantiene en memoria un modelo con el árbol visual. La UI real se sirve usando representadores de XAML con elementos nativos. El DOM en el servidor se mantiene sincronizado con la interfaz de usuario del navegador mediante un protocolo de mensajería con paquetes JSON.

Creando un proyecto

Hemos repasado los conceptos básicos, llega el momento de ver como funciona todo. Existe una plantilla de proyecto de Ooui.Forms para Visual Studio pero en este artículo vamos a crearlo todo desde cero.

Comenzamos agregando un proyecto web ASP.NET Core.

Proyecto Asp.net Core

Elegimos la plantilla utilizando MVC.

NOTA: Revisa elegir la plantilla haciendo uso de .NET Core 2.0. Ooui hace uso de la última versión de web sockets.

Tras crear el proyecto, vamos a añadir los paquetes NuGets necesarios:

Paquetes NuGets

El objetivo principal es trabajar con Xamarin.Forms en la web, por lo que también necesitamos añadir la referencia al paquete NuGet de Xamarin.Forms:

Xamarin.Forms

Llega la hora de añadir algo de código. Usaremos la configuración y enrutamiento por defecto de MVC. En Startup.cs:

app.UseOoui ();
Xamarin.Forms.Forms.Init ();

Añadimos la inicialización de Ooui dentro de ASP.net así como la inicialización de Xamarin.Forms.

Ahora continuamos añadiendo una página 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="OouiForms.Pages.MainPage">
     <ContentPage.Content>
          <StackLayout>
               <Label 
                    Text="Welcome to Xamarin.Forms!"
                    VerticalOptions="CenterAndExpand" 
                    HorizontalOptions="CenterAndExpand" />
          </StackLayout>
     </ContentPage.Content>
</ContentPage>

Para poder utilizar la página recien añadida, debemos modificar el controlador predeterminado, HomeCOntroller.cs, que por convención sirve la vista Index.cshtml para permitir que Ooui inyecte nuestra página en XAML:

public IActionResult Index()
{
     var page = new MainPage();
     var element = page.GetOouiElement();
     return new ElementResult (element, "Hello XAML!");
}

El resultado:

Hola XAML!

Aunque aún hay trabajando por delante, el proyecto cuenta con gran interés por parte de varias comunidades entre las que destaca como no podría ser de otra forma, la comunidad Xamarin. El ejemplo anterior es básico pero en estos momentos hay ya diferentes elementos XAML soportados además de enlace a datos, Converters y otras características básicas.

NOTA: Puedes ver el estado de Xamarin.Forms con Ooui en web en este enlace.

Y ahora, hablemos de WebAssembly

WebAssembly es una nueva definición de bajo nivel de Abstract Syntax Tree (AST) representada en un formato binario. Puedes pensar en ello como un lenguaje ensamblador que los navegadores web pueden ejecutar. Esto quiere decir que sería posible compilar código escrito en muchos idiomas modernos en binarios que los navegadores web ejecutan de forma nativa.

NOTA: Recomiendo también conocer Blazor, un nuevo framework de UI web experimental del equipo ASP.NET, basado en C#, Razor y HTML que se ejecuta en el navegador a través de WebAssembly. La idea es permitir a los desarrolladores escribir aplicaciones web SPA modernas que ejecuten .NET en el lado del cliente en los navegadores web utilizando estándares web.

Ahora .NET se puede ejecutar de forma nativa en el navegador con WebAssembly, sin la necesidad de complementos o extensiones. Esto es posible gracias al soporte de Mono para WebAssembly. Podemos correr código .NET (.NET Standard 2.0) incluidos navegadores móviles.

¿Probamos?

Debemos partir de una librería .NET Standard:

Librería NET Standard

Añadimos los paquetes NuGet necesarios:

Ooui.Wasm

Añade una página XAML, y tras añadir en la clase creada con la librería:

class Program
{
     static void Main (string[] args)
     {
          Forms.Init ();

          UI.Publish ("/", new MainPage ().GetOouiElement ());
     }
}

Inicializamos Xamarin.Forms y publicamos la página. Para probar, compila el proyecto. Desde una línea de comandos, accede la carpeta de salida del proyecto (bin/Debug o bin/Release) y ejecuta:

py server.py

NOTA: Si estas desde Windows debes utilizar Python 2.x.

Accede a un navegador y navega a:

http://localhost:8000

Voila!

Espera…sigo con algunas dudas…

Llegados a este punto, probablemente tengas algunas preguntas en mente.

¿Hola Silverlight?

No, suena parecido pero no es igual. Silverlight era una forma de correr Apps XAML en el navegador pero todo a base de una extensión al estilo de Flash. En este caso los elementos XAML se convierten a elementos HTML5 sin extensiones o similar.

A desarrollar webs con XAML!

No, tampoco. No al menos en estos momentos. Los desarrollo de páginas web actuales son complejos, con una interfaz muy cuidado, diferentes estados, etc. Todo avanza a buen ritmo pero en estos momentos sigue quedando mucho por hacer. Crear una herramienta de gestión, algo no excesivamente complejo es posible hoy día pero no para todo.

Más información