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

Anuncios

Crear Add-ins para Visual Studio para macOS utilizando Xamarin.Forms

Crear add-ins para Visual Studio macOS

Visual Studio para macOS esta basado en MonoDevelop. Antes de lanzarnos de lleno a crear un Add-in es importante conocer lo que se conoce como el modelo de extensión. La arquitectura de Visual Studio para macOS es extensible. La forma de extender se basa en rutas de extensión que permiten que terceros extiendan el comportamiento. Por ejemplo: para extender la zona de edición de código, se expone /MonoDevelop/SourceEditor2/ContextMenu/Editor permitiendo añadir nuevos comandos en el menu contextual al hacer clic derecho.

AddIn Maker

AddIn Maker es un proyecto Open Source creado por Mikayla Hutchinson que permite el desarrollo y la depuración de add-ins para Visual Studio macOS desde Visual Studio macOS.

Para añadirlo, nos dirimos al menu principal de Visual Studio y pulsamos sobre Addins…

Desde aquí podemos gestionar Addins en Visual Studio.

Crear proyecto de Add-in

Tras instalar AddIn Maker, tenemos accefso a un nuevo tipo de proyecto, Addin.

Seleccionamos la nueva plantilla, asignamos un nombre y continuamos.

Xamarin.Forms GTK

Llegamos a este punto, habitualmente, crearíamos nuestra interfaz de usuario utilizando GTK# o XWT. Cuando hablamos de XWT nos referimos a un tookit cross platform de UI para crear aplicaciones de escritorio con Mono y .NET.

Recientemente, hemos recibido los paquetes NuGet de la versión Preview de Xamarin.Forms 3.o. Entre las diferentes novedades encontramos soporte a Linux. El soporte de Linux se logra con un nuevo backend basado en GTK#.

Por lo que si usamos GTK#, ¿podríamos usar XAML y Xamarin.Forms para definir la UI de add-ins para Visual Studio?.

Es una posibilidad que personalmente he pensado en multitud de ocasiones e incluso lo he llegado a hablar con miembros de la comunidad Xamarin como con Matthew Robbins creador de MFRactor (tuvimos una genial conversación en el pasado MVP Summit).

Manos a la obra!

Comenzamos creando un proyecto de tipo IDE Extension:

IDE Extension

Este proyecto ya cuenta con la referencia a MonoDevelop.Addins, versión 0.4.4 al escribir este artículo. Continuamos añadiendo el paquete NuGet de Xamarin.Forms

Xamarin.Forms.Platform.GTK

Para trabajar con Xamarin.Forms, debemos realizar la inicialización. La mejor opción para realizar esta tarea es realizarla nada más se abra el IDE. Para ello, vamos a crear un comando:

public class InitXamarinFormsCommand : CommandHandler
{
     protected override void Run()
     {
          Forms.Init();
     }
}

Y modificaremos el archivo Manifiest.addin.xml para añadir nuestro comando como punto de extensión en el arranque del IDE.

<Extension path="/MonoDevelop/Ide/StartupHandlers">
      <Class class="LiveXAMLAddin.Commands.InitXamarinFormsCommand"/>
</Extension>

Llega la hora de extender. En nuestro caso, vamos a crear un sencillo Previewer de XAML para Xamarin.Forms.

NOTA: El objetivo de este ejemplo es demostrar como utilizar Xamarin.Forms para definir la UI de extensiones par Visual Studio. No estamos ante un nuevo Previewer de XAML. Aunque el funcionamiento es bastante rápido y correcto, no es el objetivo buscado.

Añadimos otro punto de extensión:

<Extension path = "/MonoDevelop/Ide/MainMenu/Edit">
     <CommandItem id="LiveXAMLAddin.Commands.PreviewXAMLCommand"/>
</Extension>

Fíjate que en esta ocasión, añadiremos un nuevo comando en el menu principal, opción editar.

Veamos la definición del comando:

public class PreviewXAMLCommand : CommandHandler
{
     protected override void Run()
     {
          Pad pad = null;

          var pads = IdeApp.Workbench.Pads;

          foreach (var p in IdeApp.Workbench.Pads)
          {
               if (string.Equals(p.Id, "LiveXAMLAddin.Pads.XAMLPreviewerPad", StringComparison.OrdinalIgnoreCase))
               {
                    pad = p;
               }
          }

          if (pad == null)
          {
               var content = new Pads.XAMLPreviewerPad();

               pad = IdeApp.Workbench.ShowPad(content, "LiveXAMLAddin.Pads.XAMLPreviewerPad", "XAML Previewer", "Right", null);

               if (pad == null)
                    return;
          }

          pad.Sticky = true;
          pad.AutoHide = false;
          pad.BringToFront();
     }

     protected override void Update(CommandInfo info)
     {
          info.Visible = true;

          if (IdeApp.Workbench.ActiveDocument != null && IdeApp.Workbench.ActiveDocument.FileName.ToString().Contains(".xaml"))
          {
               info.Enabled = true;
          }
          else
          {
               info.Enabled = false;
          }
     }
}

Reconoces a un Pad como un panel lateral anclable tanto a izquierda como derecha. En esta ocasión, creamos un nuevo Pad donde mostrar la previsualización de XAML, de título “XAML Previewer” y anclado a la derecha.

Para habilitar la opción de menu, vamos a determinar si el usuario esta editando un archivo XAML. Para ello, utilizamos IdeApp.Workbench.ActiveDocument. Tenemos posibilidad de acceder a toda la información del documento, como su formato o contenido.

Utilizando XAML para definir UI

¿Qué vamos a mostrar en el Pad?

Vamos a utilizar XAML!.  Creamos una nueva ContentPage:

<ContentPage 
     xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     x:Class="LiveXAMLAddin.Views.PreviewerView">
     <ContentPage.Content>
          <Grid>
               <ContentView
                    Content="{Binding Preview}" />
          </Grid>
     </ContentPage.Content>
</ContentPage>

Tenemos acceso a todas las opciones disponibles con XAML, entre ellas, sistema de enlace a datos, etc.  Para utilizar la página XAML como contenido del Pad vamos a embeber el contenido:

var page = new PreviewerView();
var pageContainer = page.CreateContainer();

Tenemos disponible el método de extensión CreateContainer de Xamarin.Forms en el backend GTK para obtener la ContentPage como contenido nativo.

Cafa vez que se cambie el texto de la página XAML en el editor de Visual Studio, vamos a actualizar la previsualización XAML:

IdeApp.Workbench.ActiveDocument.Editor.TextChanged += (sender , args) =>
{ 
     PreviewXaml(IdeApp.Workbench.ActiveDocument.Editor.Text);
};

Podemos utilizar MVVM (de hecho en este ejemplo se usa) en combinación con toda la potencia y las opciones de extensión que tenemos.

El resultado:

El resultado

Tienes el código fuente del ejemplo disponible GitHub:

Ver GitHub

¿Qué te parece?. Quizás en un futuro sea una opción a la hora de extender Visual Studio. Ahora que tenemos el IDE en más de un sistema operativo, es hora de pensar en contar con una opción para crear extensiones que compartan la mayor cantidad de código posible.

Más información

[Evento CartujaDotNet] Plugins, Multi-Targeting y NuGets

El evento

En un proyecto multiplataforma, una buena arquitectura y organizar de forma adecuada nuestro código nos permite compartir grandes cantidades de código entre las diferentes plataformas soportadas. Pero…¿y con otros proyectos?, ¿la comunidad?.

En este evento vamos a ver como crear librerías multiplataforma con funcionalidad específica por cada una de ellas utilizando múltiples proyectos así como el Multi-Targeting. Además, vamos a revisar las mejores opciones para compartir con la comunidad así como la creación de paquetes NuGet.

El lugar

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 B1.32
Av. Reina Mercedes s/n
Sevilla Se 41012

La fecha

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

¿Te apuntas?

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

[Xamarin] Multi-Targeting

Introducción

Con la llegada de .NET Core (y el formato project.json) llegamos a tener la opción de hacer multi-targeting. El multi-targeting no es más que compilar casi el mismo código varias veces para plataformas diferentes. Por ejemplo, con ASP.NET Core era habitual utilizar net45 o netcoreapp1.0. Más habitual era crear librerías con diferente funcionalidad basada en diferentes versiones de .NET Core. Por ejemplo, una librería con netstandard1.0 y netstandard1.4 como target.

Aunque con algunas otras plataformas (como UWP) era posible hacer algo similar no ha sido hasta el cambio a MSBuild y últimas versiones de Visual Studio 2017 donde hemos llegado a poder hacer multi-targeting con UWP, PCLs, Xamarin.Android y Xamarin.iOS.

En este artículo, vamos a conocer todos los conceptos básicos de Multi-Target así como sus beneficios a la hora de trabajar con Xamarin.

Multi-Targeting con Xamarin

Si cuentas con una librería que no requiere de código específico por plataforma no es necesario hacer multi-targeting. Como desarrolladores Xamarin, si utilizas una librería portable sin requerir código específico por plataforma, te puede interesar actualizar a una libreria .NET Standard pero sin necesidad de multi-targeting. Uno de los motivos principales para necesitar multi-target es utilizar código específico desde una librería. En estos casos, podemos tener una librería con el código común junto con N proyectos por cada plataforma que deseamos soportar. Con el uso de inyección de dependencias accedemos a la implementación específica de una plataforma. Es una forma de trabajar habitual y correcta. Sin embargo, con multi-targeting podemos tener un único proyecto con el que acceder al código de plataforma directamente.

Vamos a crear el ejemplo más básico. Partimos desde una librería .NET Standard.

Librería .NET Standard

Tras crear el proyecto, hacemos clic derecho sobre el mismo y elegimos la opción Editar:

Editar proyecto

Podemos editar el proyecto sin necesidad de descargar o cerrar el mismo viendo los cambios de forma inmediata.

Cambiamos la línea:

<TargetFramework>netstandard2.0</TargetFramework>

Por:

<TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks>

Y tras guardar cambios…

Multi-Targeting

Acontinuación, tienes el código fuente de un ejemplo disponible GitHub haciendo uso de Multi-Targeting en Xamarin:

Ver GitHubEl ejemplo es una librería con soporte a Multi-Targeting para netstandard1.0, netstandard2.0, MonoAndroid80, XamariniOS11 y uap10.0.15063.

NOTA: Se puede añadir soporte a .NET Framework, TvOS, macOS o Tizen en la misma librería con Multi-Targeting.

En el ejemplo, tenemos una interfaz IMultiTargeting con un único método:

string Sample ();

En la implementación de cada plataforma, sencillamente se devuelve una cadena con el nombre de la plataforma. Sin embargo, en cada implementación tenemos acceso a APIs nativas de la plataforma.

Ejemplo

Plugin Visual Studio para crear plantillas Multi-Targeting

James Montemagno que ya ha actualizado sus plugins para utilizar Multi-Targeting ha agrupado su experiencia en actualizar Plugin For Xamarin Templates para Visual Studio 2017 con soporte a Multi-Targeting.

Tras instalar el plugin, encontraremos dentro del conjunto de plantillas de proyecto de C# una llamada Plugin for Xamarin:

A crear nuevo plugin!

Este tipo de proyecto se encarga de preparar todo lo necesario para crear un nuevo Plugin para Xamarin para múltiples plataformas con un único proyecto utilizando Multi-Targeting:

Estructura del proyecto

Recuerda, cualquier duda o comentario es bienvenido en los comentarios!

Más información

[Xamarin] Despliegue y depuración en iOS vía WiFi

Sin cables, depuración por WiFi

Un proceso que repetimos de forma continua en el desarrollo de aplicaciones móviles con Xamarin.iOS es desplegar la aplicación en un dispositivo. Para realizar el despliegue necesitamos conectarlo al equipo de desarrollo por USB.

Hasta ahora…

La última versión de Visual Studio permite utilizar la opción de XCode de depurar iOS/tvOS para desarrolladores Xamarin. Esta nueva opción llamada WiFi debugging permite depurar aplicación Xamarin.iOS sin necesidad de conectar el teléfono vía USB.

Requisitos

Para poder utilizar WiFi debugging es necesario tener:

  • XCode 9.0
  • macOS 10.12.4
  • Visual Studio 2017 1.6 en el caso de Windows o 7.4 en macOS

NOTA: El Mac y el dispositivo deben estar conectados a la misma red.

Preparando el dispositivo

Para conectar con un dispositivo vía WiFi en depuración, necesitamos utilizar XCode. Conectamos el dispositivo por USB.

En XCode nos dirigimos a Device Manager disponible en Window > Devices and Simulators.

Aquí encontraremos al dispositivo. Tras seleccionarlo se debe marcar la opción Connect via network.

Connect via network

Todo listo!.

NOTA: Dado que el Apple TV 4K no cuenta con puerto USB esta opción se convierte en algo especialmente importante para depuración aplicaciones tvOS.

Probando la conexión

Una vez que el dispositivo (iOS 11) está configurado, no hay que configurar nada en Visual Studio. El dispositivo aparecerá en Visual Studio y podremos utilizarlo para depurar.

NOTA: Entre errores de conexión habituales se encuentran problemas de red. Se utiliza el puerto 62078 para la conexión con XCode.

Otra interesante característica añadida relacionada con la depuración vía WiFi es la capacidad de detectar si el dispositivo se encuentra bloqueado. Anteriormente si el dispositivo se encontraba bloqueado obteníamos un error en el despliegue. Ahora, Visual Studio mostrará una alerta indicando que el dispositivo se encuentra bloqueado. Si desbloqueamos, el despliegue continua. También tenemos la opciñon de cancelar deteniendo la implementación y la sesión de depuración.

Más información