[VideoBlog] Novedades en la Preview 2 de Tizen.NET

tizen_logoIntroducción

El pasado Microsoft Connect 2016, en San Francisco, Samsung en colaboración con Microsoft anunciaba la primera versión en modo Preview de las herramientas Tizen para Visual Studio.

Las herramientas Tizen para Visual Studio facilitan emuladores, extensiones para Visual Studio con la posibilidad de tener IntelliSense y capacidades de depuración, se utiliza Xamarin.Forms para definir la interfaz de usuario, como ya hacíamos con iOS Y Android. De esta forma, Xamarin.Forms añade una nueva plataforma a la que dar soporte ampliando las posibilidades del mercado.

Tizen.NET Preview 2

Recientemente, se ha liberado la Preview 2 de Tizen.NET. Una actualización importante que añade una enorme cantidad de novedades con respecto a la priemera versión lanzado el pasado Noviembre.

Tizen.NET Preview 2
Tizen.NET Preview 2

Entre el conjunto de novedades más detacadas encontramos:

  • Soporte a TV: En la primera release se incluía el soporte a .NET Standard, Xamarin.Forms y APIs Tizen de móviles. Ahora se incluyen todo lo necesario para desarrollar aplicaciones para televisores.
  • Asistente de proyecto: Dado que ahora contamos con diferentes tipos de posibles proyectos (móviles y TV), al crear un nuevo proyecto para Tizen tendremos un sencillo asistente que nos permitirá configurar las opciones básicas.
  • Nuevas herramientas: Gestión de emuladores, administrador de certificados o editor de manifiesto. Se han añadido varias herramientas nuevas para permitir desarrollar aplicaciones de forma más sencilla.
  • Nuevas APIs: Incremento alto del conjunto de APIs Tizen soportadas con respecto a la Preview anterior. Entre las novedades encontramos uso de NFC, gestión y administración de multimedia, geofence, etc.

Ante tal conjunto de novedades, ¿algo mejor que verlas todas en video?

Más información

[Xamarin.Forms] Aplicaciones Tizen

tizen_logoAplicaciones nativas multiplataforma

Xamarin.Forms es un framework que añade una capa de abstracción en la interfaz de usuario permitiendo crear aplicaciones multiplataforma nativas compartiendo el código de la UI escrito en XAML o C#.

Crear aplicaciones nativas, compartiendo grandes cantidades de código y llegar a varias plataformas son las claves del éxito Xamarin.Forms. Las plataformas soportadas actualmente son:

  • Android
  • iOS
  • Windows Phone
  • UWP

Entre la lista de peticiones y deseos relacionados con Xamarin.Forms, el acceder a más plataformas es una de las más destacadas.

Tizen aparece en escena

Tizen es un Sistema operative móviol basado en Linux, patrocinado por la Linux Foundation con el objetivo de sustentar una gran variedad de dispositivos, tabletas, móviles, wearables, dispositivos IoT, SmartTVs, etc.

Tizen en TVs
Tizen en TVs

Apoyado y utilizado por Samsung en gran variedad de dispositivos brilla por su ligereza (requiere hardware menos potente) ayudando al equilibro y consumo.

Actualmente disponible en más de 50 millones de dispositivos Samsung incluidas SmartTVs, wearables, dispositivos IoT y teléfonos.

El pasado Microsoft Connect 2016, en San Francisco, Samsung en colaboración con Microsoft anunciaba la primera versión en modo Preview de las herramientas Tizen para Visual Studio.

Tizen.NET
Tizen.NET

Las herramientas Tizen para Visual Studio facilitan emuladores, extensiones para Visual Studio con la posibilidad de tener IntelliSense y capacidades de depuración, se utiliza Xamarin.Forms para definir la interfaz de usuario, como ya hacíamos con iOS Y Android. De esta forma, Xamarin.Forms añade una nueva plataforma a la que dar soporte ampliando las posibilidades del mercado.

Tizen.NET, características y componentes

Tizen.NET se basa en un conjunto de componentes:

  1. .NET Core
  2. Forms como framework de UI
  3. APIs específicas de Tizen

.NET Core

.NET Core es la plataforma de desarrollo llevada a cabo por Microsoft y la comunidad .NET disponible en GitHub. Con la multiplataforma como clave destacada, soporta Windows. MacOS y Linux, además se puede utilizar en dispositivos, la nube o en escenarios emebebidos o IoT.

.NET Core contiene las siguientes partes:

  • El .NET runtime, otorga la carga de ensamblados, el garbage collector, interoperabilidad nativa, y otros servicios básicos.
  • Un conjunto de librerías que facilitan utilidades fundamentales, tipos de datos primitivos, etc.
  • Un conjunto de herramientas de SDK y de compiladores del lenguaje que permiten completar todas las necesidades en el desarrollo. Disponibles en el .NET Core SDK.

El uso de .NET native ofrece grandes ventajas:

  • Tiempos de ejecución más rápidos
  • Tiempos de arranque más rápidos
  • Coste bajo en despliegues
  • Optimización en el uso de memoria

Xamarin.Forms como framework de UI

Xamarin.Forms es un toolkit multiplataforma pata crear interfaces de usuario de forma eficiente y compartida entre iOS, Android y Windows. Tizen.NET soporta el 99% de características de Xamarin.Forms. Las limitaciones son:

  • AppLinkEntry
  • PinchGestureRecognizer
  • PanGestureRecognizer
  • OpenGLView
  • WebView
  • OnPlatform<T>
  • PlatformEffect<TContainer, TControl>

APIs específicas de Tizen

Tizen.NET nos permite trabajar con la plataforma utilizando C#, es decir, expone las APIs nativas de Tizen como las de localización o conectividad. Actualmente, utilizando C# tenemos soporte para el 60% de las APIs de Tizen.

tizen-architecture

Las APIs soportadas de Tizen son:

  • Applications: Aporta el conjunto de APIs relacionado con la aplicación tales como la gestión de eventos relacionados con el estado de la aplicación.
  • Content: Descarga de contenido, almacenamiento, asociaciones de tipos.
  • Location: Localización geográfica y geofencing.
  • Multimedia: Servicios multimedia incluido audio o grabación.
  • Network: Control del estado de la conectividad o accede a información de la red.
  • Security: Almacenamiento seguro para almacenar contraseñas o claves.
  • System: Servicios específicos del Sistema, obtener información del estado, información del sistema, etc.

La instalación

Comenzamos accediendo a la documentación oficial de Tizen.NET donde tenemos acceso al instalador.

Descarga
Descarga
Descargar Tizen.NET
Descargar Tizen.NET

Tras la descarga del archivo, debemos realizar la instalación de las herramientas Tizen.NET.

Setup
Setup

Al completar la instalación debemos tener todo lo necesario.

A tener en cuenta:

  • Se requiere una maquina con un procesador de 64 bits.
  • Para lanzar el emulador se requiere Intel HAXM. Hyper-V debe estar deshabilitado.

Creando una aplicación para Tizen desde Visual Studio

Las herramientas de Tizen para Visual Studio incluyen:

  • Emulador: Utiliza una imagen de Tizen 3.0 (beta) con soporte a aplicaciones .NET. Versiones anteriores del emulador a pesar de poder utilizarlos desde Visual Studio, no tienen soporte a .NET.
  • APIs: Sólo se añaden en la primera Preview APIs móviles.
  • Extensiones: Mediante dos extensiones se añade soporte a la edición, depuración o compilación del proyecto.
Extensiones Tizen en Visual Studio
Extensiones Tizen en Visual Studio

Vamos a crear un proyecto Xamarin.Forms con soporte a Tizen. A la hora de crear el proyecto, contamos con diferentes plantillas de proyectos.

Plantillas Tizen
Plantillas Tizen

Bajo la pestaña Tizen encontramos:

  • Blank App (Tizen Xamarin.Forms Portable): Crea una solución con una librería portable y un proyecto nativo Tizen.NET.
  • Blank App (Tizen Xamarin.Forms Single): Sólo crea el proyecto Tizen. Idóneo para añadir a una solución Xamarin.Forms ya preparada.
  • Class Library (Tizen): Librería con Soporte a Tizen.

Seleccionamos la primera opción. Tras crear el Proyecto veremos una solución con dos proyectos:

  • Un proyecto nombrado <projectname> de tipo portable que contiene todo el código Xamarin.Forms.
  • Otro proyecto llamado <projectname>.Tizen que contiene todo el código necesario para inicializar la aplicación con el framework Tizen.

Para desplegar la aplicación en el emulador bastara con pulsar F5 o pulsar el botón Play.

Compilar
Compilar

Tras unos segundos el icono de la aplicación debe aparecer en el emulador permitiendo el acceso a la misma.

La App desde la plantilla en ejecución
La App desde la plantilla en ejecución

NOTA: El primer arranque del emulador se encarga de desempaquetar la imagen necesario. El proceso puede tardar unos minutos.

A continuación, vamos a crear una aplicación con algo de entidad utilizando MVVM para mostrar un listado de monos.

Sin embargo, antes de comenzar, vamos a repasar la estructura del proyecto para conocer todo lo necesario relacionado. Vamos a ignorar el contenido de la librería portable al ser exactamente igual a todo lo que ya teníamos en Xamarin.Forms.

En el proyecto Tizen tenemos:

  • Una carpeta llamada shared que contendrá elementos relacionados con la aplicación. El icono de la aplicación se encuentra empaquetado en el directorio shared/res.
  • La carpeta res contendrá recursos para la aplicación. Por ejemplo, si la aplicación necesita un archivo en tiempo de ejecución, este es su lugar.
  • La carpeta lib contiene el código generado de la aplicación.

También tenemos un archivo de vital importancia, tizen-manifiest.xml. Hablamos del archivo de manifiesto, un archivo de configuración donde se especifican datos básicos de la aplicación como nombre, icono, paquete, etc.

Tras analizar la estructura del proyecto, continuamos con nuestra aplicación. Comenzamos creando la estructura base de carpetas:

tizen-project-structure

Continuamos creando el modelo de datos, una clase llamada Monkey que definirá a cada mono del listado:

public class Monkey
{
    public string Name { get; set; }

    public string Location { get; set; }

    public string Details { get; set; }

    public string Image { get; set; }
}

Continuamos definiendo la vista modelo, encargada de preparar toda la colección de monos a mostrar en la UI:

public class MonkeysViewModel
{

   public ObservableCollection<Monkey> Monkeys { get; set; }

    public MonkeysViewModel()
    {
        Monkeys = new ObservableCollection<Monkey>
        {
            new Monkey
            {
                Name = "Baboon",
                Location = "Africa & Asia",
                Details = "Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.",
                Image = "http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
            },
                  ...
            };
      }
}

Por último, llega el momento de definir la UI. Para ello utilizaremos la vista principal 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="TizenMonkeys.Views.MonkeysView"
             xmlns:templates="clr-namespace:TizenMonkeys.Views.Templates;assembly=TizenMonkeys"
             Title="Monkeys Tizen.NET">
    <ListView
        ItemsSource="{Binding Monkeys}"
        RowHeight="80"
        HasUnevenRows="true">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <templates:MonkeyItemView/>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Si compilamos y ejecutamos el proyecto:

Voila!
Voila!

Impresionante, ¿verdad?

Recuerda, cualquier tipo de duda o sugerencia es bienvenida en los comentario del artículo. Tizen.Net nos abre un mundo de posibilidades de forma sencilla al abrirnos el abanico de dispositivos soportados. ¿Y tú que opinas?.

Tizen.Net, ¿qué es lo próximo?

El objetivo marcado es continuar añadiendo extensiones que faciliten la creación de grandes aplicaciones. Los puntos en el camino próximo son:

  • Mayor soporte a APIs de Tizen.
  • Añadir diferentes perfiles (TV, mobile).
  • Se subirá próximamente el código fuente (como el resto de Xamarin.Forms está disponible en GitHub).
  • Mayor cantidad de ejemplos utilizando Tizen.NET.

[Material] Xamarin Dev Day Madrid

El evento

El pasado sábado 26 de Noviembre, tenía lugar en Madrid el Xamarin Dev Days. Una jornada con varias sesiones técnicas, taller, regalos y mucho networking.

El resultado fue un fantástico día de desarrollo Xamarin con muchas preguntas, ayuda y tiempo para charlar entre todos rodeados de un café o unas pizzas.

El material

Pude participar en el evento con una de las sesiones. Nos centramos en el desarrollo de aplicaciones móviles multiplataforma utilizando Xamarin.Forms:

Comenzamos por una introducción de conceptos básicos, primera demo aplicando MVVM y terminamos repasando todas las últimas novedades como DataPages, Native Views o el desarrollo para Tizen.

Tras las sesiones, realizamos un muy divertido taller donde paso a paso, desarrollamos una aplicación Xamarin.Forms aplicando MVVM y accediendo a información meteorológica.

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Quisiera terminar añadiendo algunos agradecimientos. Comienzo por los chicos de Liferay por las instalaciones y toda la ayuda; a Plain Concepts y Bravent por su patrocinio; a Xamarin también por patrocinar el evento; a mis compañeros Dachi Gogotchuri, Sergio Gasca, Ramón Esteban y Alejandro Campos por sus demos y ayudar con todo y por supuesto a los asistentes. Gracias a todos.

Más información

[Xamarin.Forms] Un vistazo al uso de Native Views desde XAML

XamarinIntroducción

Xamarin.Forms añade una capa de abstracción sobre la capa de la interfaz de usuario que permite definir la misma una única vez para todas las plataformas con código C# o XAML. A pesar de la abstracción, podemos acceder a características específicas de la plataforma utilizando DependencyService o crear nuevos controles accediendo a características nativas gracias al uso de Custom Renders, efectos o Native Embbeding.

En el uso de Custom Renders o efectos, necesitamos crear una clase en la PCL con la definición del control o efecto y una clase en cada plataforma soportada con la implementación.

¿Y si se puede hacer todo de una forma más directa?

Native Views

Con Xamarin.Forms 2.3.3.+se introduce el concepto de Native Views. Se pueden incrustar directamente vistas nativas en el XAML de nuestra interfaz compartida ya sea utilizando proyectos compartidos o librerías portables.

Uso en Android

Añadir vistas nativas es realmente sencillo. Necesitamos declarar los namespaces XML (xmlns) necesarios:

xmlns:android="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
xmlns:androidForms="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"

Tras añadir los namespaces correspondientes, podemos acceder directamente a controles nativos:

<android:CalendarView         
     x:Arguments="{x:Static androidForms:Forms.Context}" />

Podemos acceder directamente a las propiedades del control nativo como atributos XML. En caso de requerir el uso de argumentos podemos establecerlo utilizando x:Arguments.

En Android es necesario pasar el contexto de Xamarin.Forms. En caso contrario obtendremos un error:

System.MissingMethodException: Default constructor not found for type Android.Widget.xxxxx

El resultado:

Calendario nativo de Android
Calendario nativo de Android

El turno de iOS

En el resto de plataformas, es practicamente igual el uso de Native Views. Comenzamos definiendo el namespace necesario:

xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"

Y podemos acceder directamente a controles nativos:

<ios:UIDatePicker />

El resultado:

UIDatePicker
UIDatePicker

Y ahora Windows

En el caso de Windows, igualmente necesitamos declarar el namespace:

xmlns:uwp="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"

Y tenemos acceso a vistas nativas:

<uwp:CalendarDatePicker />

El resultado:

nativeviews-windows
CalendarDatePicker

Utilizando Native Views

Tras definir tres vistas, cada una con vistas nativas de cada plataforma, para utilizarlas en una página debemos definir el namespace correspondiente:

xmlns:nativeViews="clr-namespace:NativeViews.Views.Native"

Y añadir cada vista:

<Grid>
     <nativeViews:AndroidView />
     <nativeViews:IosView />
     <nativeViews:WindowsView />
</Grid>

Sencillo, ¿cierto?.

¿Qué ocurre al ejecutar la aplicación y cargar esta vista en Android (por ejemplo)?.

Sólo se renderizarán los elementos Xamarin.Forms y la vista nativa de Android. No se mostrará nada relacionada con las visats nativas de iOS o Windows. Igual comportamiento obtendremos en otras plataformas.

Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Recuerda, cualquier tipo de duda o sugerencia es bienvenida en los comentario del artículo.

Atener en cuenta

A la hora de utilizar Native Views en nuestros desarrollos hay que tener en cuenta que:

  • No se puede utilizar Native Views en una vista con XAMLC (compilación de XAML) activado.
  • No podemos utilizar x:Name en controles nativos.

one-more-thingOne more thing

La posibilidad de añadir directamente vistas nativas en el XAML de nuestras vistas compartidas en Xamarin.Forms es una nueva característica interesante pero en la mayoría de ocasiones nos interesará gestionar de una forma adecuada la interacción con los controles.

Native Views permite el uso de enlace a datos tanto en modo OneWay como TwoWay. Gracias a esta posibilidad podemos crear vistas realmente complejas de una forma más simple. En próximos artículos continuaremos profundizando en el concepto de Native Views centrándonos en el uso de enlace a datos. Permanece atento!

Más información

[Xamarin.Forms] Introducción al uso de efectos

Introducción

Xamarin.Forms añade una capa de abstracción sobre la capa de la interfaz de usuario permitiendo definir la misma una única vez siendo válida para todas las plataformas.

Xamarin.Forms
Xamarin.Forms

Cuenta con páginas, layouts y controles que son renderizados de forma diferente en cada plataforma. Se utiliza una clase Renderer distinta en cada plataforma y encargada de crear un control nativo y añadirlo en pantalla.

¿Qué es un efecto?

Un efecto permite el acceso al control nativo de cada plataforma con el objetivo de personalizarlo, principalmente aplicando pequeños cambios estéticos o de comportamiento. Permiten simplificar la personalización del control y sobretodo se convierten en «piezas» reutilizables de código incluso aceptando parametrización.

¿Por qué usar efectos y no un Custom Renderer?

Tener acceso a un control nativo, poder personalizarlo y además tenerlo todo en una pieza reutilizable está al alcance de nuestra mano gracias al uso de efectos.

¿Cuándo utilizamos entonces un Custom Renderer, y cuándo un efecto?

  • Si necesitamos crear un nuevo control o  reemplazar el control específico implementado por Xamarin.Forms de una plataforma, necesitamos un Custom Renderer.
  • Si sólo necesitamos modificar o añadir alguna propiedad que modifica la apariencia o comportamiento del control nativo implementado por Xamarin.Forms, efecto.

Crear un efecto

El proceso de creación de un efecto, se puede resumir en una serie de sencillos pasos:

  1. Crear en la PCL una clase que herede de RoutingEffect. Código independiente de la plataforma encargado de hacer el wrapping del efecto. Podemos definir distintas propiedades que permitan modificar la acción realizada por el efecto. Por ejemplo, en un efecto encargado de aplicar Blur a una imagen, se puede definir una propiedad encarga de aplicar mayor o menor distorsión.
  2. Crear clases en cada plataforma soportada que hereden de PlatformEffect.
  3. Sobrecargar el método OnAttached y añadir la lógica de personalización del control.
  4. Sobrecargar el método OnDetached y añadir lógica de liberación de recursos.
  5. Añadir el atributo ResolutionGroupName. Este atributo permite establecer el nombre del creador o compañia tras el efecto. Recuerda que uno de los objetivos fundamentales de los efectos es lograr permitir compartir y reutilizar con suma facilidad. Con este atributo se previenen colisiones con otros efectos que compartan nombre.
  6. Añadir el atributo ExportEffect. Este atributo registra el efecto con un identificador único usado por Xamarin.Forms, junto al nombre del grupo, permite localizar y aplicar el efecto.

Para comprender el proceso de creación de un efecto vamos a crear uno paso a paso. Nuestro efecto será simple, permitirá aplicar el efecto blur a una imagen.

Comenzamos en la PCL. Dentro de la carpeta Effects, creamos una clase que herede de RoutingEffect:

public class BlurredEffect : RoutingEffect
{
     public string Url { get; set; }
     public int Radius { get; set; }

     public BlurredEffect() : base("Xamarin.BlurredImageEffect")
     {

     } 
}

Además de la implementación del constructor, donde indicamos el nombre del grupo y del efecto que utilizaremos en la implementación de cada plataforma, añadimos dos propiedades:

  • Url: La Url de la imagen a la que aplicaremos el efecto.
  • Radius: Un entero que permite establecer el nivel de distorsión aplicado. A valores más altos, mayor nivel de distorsión.

Tras la creación de la «definición» de lo que será nuestro servicio, pasamos al código específico por plataforma. Se deben de crear clases que hereden de PlatformEffect:

public class BlurredImageEffect : PlatformEffect  
{

}

PlatformEffect provocará la necesidad de implementar los métodos OnAttached y OnDetached:

protected override void OnAttached() 
{

}

protected override void OnDetached()    
{
        
}

Vamos a comprender el objetivo de cada método:

  • OnAttached: Lanzado cuando un efecto se adjunta un control Xamarin.Forms. La sobrecarga de este método en cada plataforma es el lugar idóneo para añadir código específico de plataforma que afecte al control ya sea en su apariencia o en su comportamiento.
  • OnDetached: Este método se lanza cuando el efecto se quita del control Xamarin.Forms. La sobrecarga permite añadir código específico de liberación de recursos y limpieza.

Aunque no lo usamos en nuestro efecto de blur, PlatformEffect expone el método OnElementPropertyChanged. Este método se lanza cuando una propiedad del efecto cambia. Lugar idóneo para responder a cambios de la propiedades.

Implementamos el código del método OnAttached en Android:

protected override void OnAttached()
{
     try
     {
          var imageView = Control as ImageView;
          var effect = (BlurredEffect)Element.Effects.FirstOrDefault(e => e is BlurredEffect);
          if (effect != null)
          {
               var d = imageView.Drawable;
               if (d != null)
               {
                    var bitmap = GetImageBitmapFromUrl(effect.Url);

                    if (bitmap != null)
                    {
                        imageView.SetImageBitmap(CreateBlurredImage(effect.Radius, bitmap));
                        imageView.Invalidate();
                    }
                }
          }
     }   
     catch (Exception ex)
     {
          Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
     }
}

Cada clase específica de plataforma que hereda de PlatformEffect cuenta con:

  • Control: Control nativo usado por Xamarin.Forms como implementación del control Xamarin.Forms. Por ejemplo, en Android en el caso de una Image, hablaríamos de un ImageView.
  • Element: Control Xamarin.Forms renderizado.

Analicemos el código anterior. Comienza accediendo al efecto, disponible en la colección Effects del control representado por Element.

Tras acceder al efecto, se crea un Bitmap partiendo de la Url recibida como parámetro en la propiedad Url, y se aplica el efecto Blur utilizando la imagen anterior y aplicando el grado de distorsión utilizando la propiedad Radius.

El método encargado de crear el Bitmap en base a la Url:

prprivate Bitmap GetImageBitmapFromUrl(string url)   
{            
     Bitmap imageBitmap = null;
          
     using (var webClient = new WebClient())
     {
          var imageBytes = webClient.DownloadData(url);
          if (imageBytes != null && imageBytes.Length > 0)
          {
               imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
          }
     }

     return imageBitmap;
}

Utiliza un WebClient para descargar la información de la imagen y BitmapFactory para crear el Bitmap usando los datos descargados.

El método encargado de aplicar el efecto Blur:

private Bitmap CreateBlurredImage(int radius, Bitmap originalBitmap)
{
     Bitmap blurredBitmap;
     blurredBitmap = Bitmap.CreateBitmap(originalBitmap);

     var rs = RenderScript.Create(Forms.Context);
     var input = Allocation.CreateFromBitmap(rs, originalBitmap, Allocation.MipmapControl.MipmapFull, AllocationUsage.Script);
     var output = Allocation.CreateTyped(rs, input.Type);

     var script = ScriptIntrinsicBlur.Create(rs, Android.Renderscripts.Element.U8_4(rs));
     script.SetInput(input);
     script.SetRadius(radius);
     script.ForEach(output);

     output.CopyTo(blurredBitmap);

     return blurredBitmap;
}

Basado en RenderScript para aplicar el efecto.

Nos faltaría aplicar las etiquetas que permitan establecer el nombre del grupo y la exportación del efecto:

[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(BlurredImageEffect), "BlurredImageEffect")]

De igual forma, en otras plataformas (iOS y Windows) se debe de crear la clase e implementar PlatformEffect.

Utilizar un efecto

Desde la PCL, en la vista compartida definida en XAML, para utilizar el efecto se debe utilizar el espacio de nombre donde se ha definido:

xmlns:effects="clr-namespace:BlurImageEffect.Effects"

Y utilizarlo:

<Label 
     Text="Image"/>
<Image
     Source="https://www.xamarin.com/content/images/pages/branding/assets/xamarin-logo.png"/>
<Label 
      Text="Blurred Image"/>
<Image>
     <Image.Effects>
        <effects:BlurredEffect
             Url="https://www.xamarin.com/content/images/pages/branding/assets/xamarin-logo.png"
             Radius="20"/>
     </Image.Effects>
</Image>

El efecto BlurredEfect se adjunta a la segunda imagen añadiéndolo a la colección Effects. Xamarin.Forms utilizará Effect.Resolve para devolver el efecto especificado utilizando una concatenación del nombre de grupo (ResolutionGroupName) junto a su identificador (especificado con el atributo ExportEffect).

El resultado:

BlurredImageEffect
BlurredImageEffect

Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Recuerda, cualquier tipo de duda o sugerencia es bienvenida en los comentario del artículo.

Más información

[Xamarin.Forms] Utilizando DataPages

Forms-01-WFIntroducción a DataPages

En no pocas ocasiones nos planteamos realizar una aplicación sencilla para consultar información existente desde un servidor o infraestructura cloud.

En el marco del pasado Evolve 2016, Xamarin anunciaba la disponibilidad e la preview de Xamarin.Forms DataPages.

Los DataPages llegan para facilitar la creación de aplicaciones de tipo maestro-detalle con acceso a una fuente de información de la forma más rápida y sencilla posible. Se renderizarán listados y detalles automáticamente en base a los datos pudiendo personalizar con el uso de diferentes controles y el uso de temas.

DataPages se puede utilizar consumiendo el paquete NuGet Xamarin.Forms.Pages.

Permite acceder a diferentes fuentes de información con data sources prefabricados:

  • JsonDataSource: Una URL que contiene un JSON.
  • AzureDataSource (paquete NuGet separado): Azure Mobile Services.
  • AzureEasyTableDataSource (paquete NuGet separado).

Para mostrar la información correspondiente a la fuente de información contamos con una serie de páginas y controles.

Las páginas disponibles son:

  • ListDataPage: Muestra un listado de elementos.
  • DirectoryPage: Listado de elementos agrupados.
  • PersonDetailPage: Página de detalles que muestra la información correspondiente a un tipo de objeto.

En cuanto a controles:

  • ListItem: Vista prefabricada destinado a mostrar un elemento de un listado. Puede mostrar título, detalles e imagen.
ListItem
ListItem
  • CardView: Este control es similar al CardView nativo de Android. Permite mostrar un texto principal, uno secundario y una imagen.
CardView
CardView
  • HeroImage: Control que permite mostrar título, detalles e imagen, dándole peso a esta última. Tambien cuenta con una propiedad para modificar el aspecto.
HeroImage
HeroImage

Preparando la solución

Comenzamos creando una aplicación Xamarin.Forms utilizando una librería portable (PCL):

Nueva aplicación Xamarin.Forms
Añadir paquetes utilizando NuGet

Nueva aplicación Xamarin.Forms

Tras crear el proyecto debemos añadir la referencia a DataPages y Themes. Para ello, utilizaremos NuGet para añadir:

  • Xamarin.Forms.Pages
  • Xamarin.Forms.Theme.Base
  • Xamarin.Forms.Themes.Light o Xamarin.Forms.Themes.Dark
Añadir paquetes utilizando NuGet
Añadir paquetes utilizando NuGet

NOTA: Debemos añadir los paquetes NuGet tanto en la libería portable como en el proyecto específico de cada plataforma, tanto en iOS como en Android.

DataPages requiere el uso de temas para poder renderizar correctamente. Para ello, en App.xaml debemos añadir el namespace detema y añadirlo en los recursos de la aplicación.

Dependiendo del tema elegido, los espacios de nombre a utilizar son:

xmlns:light="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Light"    
xmlns:dark="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Dark"

Y para añadir el tema a utilizar dentro del conjunto de recursos de la aplicación:

<ResourceDictionary MergedWith="dark:DarkThemeResources" />        
<ResourceDictionary MergedWith="light:LightThemeResources" />

Por ahora, para completar el proceso de uso del tema, debemos añadir algo de código específico por cada plataforma para cargar las librerías correspondientes.

var x = typeof(Xamarin.Forms.Themes.DarkThemeResources);    
x = typeof(Xamarin.Forms.Themes.LightThemeResources);    
x = typeof(Xamarin.Forms.Themes.Android.UnderlineEffect);

En el caso de iOS código a ejecutar en el AppDelegate, en el de Android, en la actividad principal MainActivity.

Ejemplo básico

Añadimos la vista XAML principal de la aplicación. Incluimos el espacio de nombres correspondiente a DataPages para acceder y utilizar las páginas, controles y data sources incluidos.

xmlns:p="clr-namespace:Xamarin.Forms.Pages;assembly=Xamarin.Forms.Pages"

Añadimos:

<?xml version="1.0" encoding="UTF-8"?>
<p:ListDataPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:p="clr-namespace:Xamarin.Forms.Pages;assembly=Xamarin.Forms.Pages"
             x:Class="DataPagesDemo.SessionDataPage"
             Title="Sessions" StyleClass="Events">
    <p:ListDataPage.DataSource>
        <p:JsonDataSource Source="http://demo3143189.mockable.io/sessions" />
    </p:ListDataPage.DataSource>
</p:ListDataPage>

El resultado:

El resultado
El resultado

Increíble, ¿cierto?. Vamos a analizar el código  (escaso) añadido.

Hemos modificado el tipo de página de una ContentPage, página básica para añadir contenido en Xamarin.Forms por una ListDataPage. Xamarin.Forms DataPages nos ofrece este tipo de página que nos permite crear un maestro-detalle con suma facilidad en base una fuente de información.

Utilizando la propiedad DataSource de la página, creamos un JsonDataSource que se encargará de acceder a la información realizando la petición HTTP necesaria y parseando la información para permitir mostrarla en la UI realizando bindings.

¿Dónde realizamos el enlace de la UI con la información?. La propiedad StyleClass de la página permite acceder a un estilo. En este caso se utiliza «Events», estilo prefabricado que ya define lo necesario para enlazar correctamente con la fuente de información («title», «image», «presenter»).

Tenéis el código fuente del ejemplo básico disponible en GitHub:

Ver GitHub

Añadiendo personalización

Vamos a crear un segundo ejemplo donde personalizar aspectos como la fuente de información, el aspecto visual modificando controles utilizados y por supuesto, también los enlaces a la información.

Vamos a generar una fuente de información de pruebas utilizando Json generator. Reemplazamos la fuente utilizando el datasource de tipo JsonDataSource:

<p:ListDataPage.DataSource>
     <p:JsonDataSource Source="http://www.json-generator.com/api/json/get/clOPFoTImW?indent=2" />
</p:ListDataPage.DataSource>

A continuación, vamos a modificar la propiedad DefaultItemTemplate que permite especificar la apariencia de cada elemento dentro del listado. En lugar de utilizar el control CardView utilizado por defecto en el ejemplo anterior, vamos a utilizar un ListItem.

<p:ListDataPage.DefaultItemTemplate>
     <DataTemplate>
          <ViewCell>
               <p:ListItemControl
                    Title="{p:DataSourceBinding name}" 
                    Detail="{p:DataSourceBinding email}" 
                    ImageSource="{p:DataSourceBinding picture}"
                      DataSource="{Binding Value}">
               </p:ListItemControl>
          </ViewCell>
     </DataTemplate>
</p:ListDataPage.DefaultItemTemplate>

ListItem cuenta con propiedades Title, Detail e ImageSource para especificar sus valores, utilizando la palabra reservada DataSourceBinding enlazaremos con los campos deseados del archivo JSON.

Nuestra página quedaría finalmente:

<p:ListDataPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:p="clr-namespace:Xamarin.Forms.Pages;assembly=Xamarin.Forms.Pages"
             x:Class="DataPages.MainView"
                   StyleClass="Events" 
                   Title="Users">   
    <p:ListDataPage.DataSource>
        <p:JsonDataSource Source="http://www.json-generator.com/api/json/get/clOPFoTImW?indent=2" />
    </p:ListDataPage.DataSource>
    <p:ListDataPage.DefaultItemTemplate>
        <DataTemplate>
            <ViewCell>
            <p:ListItemControl
                Title="{p:DataSourceBinding name}" 
                Detail="{p:DataSourceBinding email}" 
                ImageSource="{p:DataSourceBinding picture}"
                  DataSource="{Binding Value}">
                </p:ListItemControl>
            </ViewCell>
        </DataTemplate>
    </p:ListDataPage.DefaultItemTemplate>
</p:ListDataPage>

Tras ejecutar:

Personalización
Personalización

Además de contar con el listado, tenemos también disponible la vista de detalles mostrando más información a partir de los diferentes datos del JSON.

Y hasta aquí el repaso a las posibilidades de Xamarin.Forms DataPages. Una forma bastante rápida y sencilla para crear aplicaciones sencillas o prototipos con posibilidades interesantes en personalización y extensión. Siempre repitiendo cuatro sencillos pasos:

  1. Instalar paquetes NuGet.
  2. Seleccionar tema.
  3. Añadir DataPage.
  4. Configurar data source y personalización.

Tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

¿Y próximamente?

DataPages continuará evolucionando y madurando con varios objetivos en mente. Xamarin ya ha confirmado que:

  • En próximas versiones no necesitaremos añadir código específico de plataforma para realizar la carga de las librerías correspondientes a temas.
  • Se incluirá la posibilidad de CRUD (create-read-update-delete).

Más información

[VideoBlog] Un vistazo a XenForms

XenFormsIntroducción

Xamarin.Forms es un framework que añade una capa de abstracción sobre la parte de UI permitiendo crear aplicaciones multiplataforma nativas compartiendo tanto la lógica de negocio como la interfaz de usuario. En los últimos tiempos hemos ido recibiendo tanto por parte de Xamarin como por parte de la comunidad gran cantidad de mejoras para aumentar el rendimiento en el desarrollo como el editor visual, Xamarin.Forms Previewer o Gorilla Player.

XenForms

La comunidad sigue creciendo a un ritmo imparable ofreciendo cada vez más y mejores opciones. Hoy estamos ante XenForms, herramienta creada por Michael Davis destinada a editar interfaces en Xamarin.Forms. Permite crear interfaces partiendo desde cero añadiendo Layouts y Views.

Construyendo la UI desde cero
Construyendo la UI desde cero

Además de poder editar cada propiedad de cada elemento, o los eventos.

Modificación de propiedades
Modificación de propiedades

También podemos cargar un proyecto ya existente para previsualizar la interfaz, hacer cambios al vuelo con el editor visual editando propiedades, hacer cambios a nivel de XAML, etc.

Carga de proyectos existentes
Carga de proyectos existentes

Suena interesante, ¿cierto?. Si te lo parece, no te pierdas el siguiente recorrido por la herramienta en video.

También se puede trabajar con Apps utilizando MVVM realizando pruebas de enlaces a datos (interactuar con la aplicación a la par que se edita), uso de propiedades avanzadas y adjuntas, etc.

Una herramienta interesante y sin duda con mucho potencial, ¿y a ti, qué te parece?.

Más información

[VideoBlog] Un vistazo a Xamarin.Forms Previewer

Introducción

Xamarin.Forms es un framework que añade una capa de abstracción sobre la parte de UI permitiendo crear aplicaciones multiplataforma nativas compartiendo tanto la lógica de negocio como la interfaz de usuario. En el pasado Evolve 2016 se mostraron novedades de peso permitiendo aumentar el rendimiento en el desarrollo además de nuevas caracterísiticas.

Xamarin.Forms Previewer

Hasta ahora, cada vez que queríamos previsualizar un cambio de una vista en Xamarin.Forms requería una compilación y despliegue de la aplicación a un emulador o dispositivo físico. No es de extrañar que una de las opciones más solicitadas en el trabajo con Xamarin.Forms fuese un editor visual. Gracias a un editor visual podríamos ver cada cambio al vuelo, de forma inmediata sin necesidad de compilaciones ni despliegues incrementando considerablemente nuestra productividad. La espera ha llegado a su fin. Xamarin ha lanzado la Preview (disponible para Xamarin Studio) de Xamarin.Forms Previewer, editor visual para Xamarin.Forms.

Además de poder previsualizar cualquier cambio en nuestro marcado XAML directamente al vuelo, Xamarin.Forms Previewer es capaz de:

  • Podemos cambiar la previsualización en iOS y Android rápidamente además de tamaños y orientación.
  • Mostrar Custom Renders.
  • Mostrar datos de prueba en diseño.

Ante una novedad de tanto peso, no es de extrañar que en este nuevo VideoBlog nos lancemos de lleno a probar todas las opciones disponibles.

Tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

[Xamarin.Forms] Adaptando aplicaciones para Tablets

Tablet HoldIntroducción

Corría el año 2010, finales de Enero, cuando Steve Jobs presentaba al mundo el iPad. El resto de la historia todos la conocemos. No era la primera tableta del mundo, ni la que más posibilidades brindaba pero si que fue sin duda un momento importante en el mercado. La sucesión de modelos por parte de los chicos de Cupertino, la explosión vivida en factores, formas y rangos de precios en tabletas Android y también la evolución de tabletas y crecimiento de éxito en tabletas Windows y equipos duales demuestran el crecimiento e importancia en el sector de las tabletas.

Como desarrolladores nos afecta de forma directa. Cuando desarrollamos aplicaciones móviles, es importante tener en cuenta no solo diversas plataformas, también factores de forma incluyendo tabletas. Al desarrollar una aplicación móvil multiplataforma con Xamarin.Forms además de compartir la lógica de negocio, compartimos la interfaz de usuario.

Teniendo en cuenta que las vistas son compartidas, ¿cómo adaptamos una aplicación Xamarin.Forms a tabletas?. En este artículo, vamos a repasar todos los detalles y aspectos a tener en cuenta para lograr ofrecer la mejor experiencia posible en cada formato.

Nuestra aplicación móvil

Para adaptar una aplicación Xamarin.Forms móvil a tabletas necesitamos…una aplicación. Vamos a partir de un proyecto con una aplicación móvil para todas las plataformas que muestra información relacionada con la Formula 1. Cuenta con posibilidad de ver pilotos con sus estadísticas, circuitos, escuderías, etc.

Interfaz en teléfonos
Interfaz en teléfonos

La aplicación utiliza servicios web para acceder a la información y muestra la misma de diversas formas, desde información numérica a formato más visual como gráficas.

Nuestro objetivo será adaptar la aplicación a tabletas adaptando la interfaz de usuario, la navegación y los recursos utilizados.

Añadiendo soporte a Tabletas

Antes de adaptar estilos, vistas, navegación o recursos, debemos asegurarnos que la aplicación nativa en cada plataforma soportan las tabletas.

iOS

En el caso de iOS, es decir, iPads, la plantilla automática de Xamarin.Forms incluye soporte. Podemos revisarlo verificando si la propiedad Info.plist > Devices tiene asignado el valor Universal.

Android

El ecosistema Android es bastante variado y complejo contando con una enorme diversidad de tamaños de pantalla. Desde Apps Xamarin.Forms tenemos soporte a toda la variedad.

Windows

Xamarin.Foms cuenta con soporte a aplicaciones Universal Windows Platform también conocido por las siglas en inglés UWP. Las aplicaciones Universales en Windows 10 permite acceder a una enorme variedad de familias de dispositivos, desde teléfonos a tabletas y PCs.

Detectando si estamos en teléfono o tableta

Para poder modificar el comportamiento de la aplicación dependiendo de si estamos en un teléfono o una tableta, necesitamos verificar si estamos en uno u otro. Podemos utilizar la clase Device para acceder a la enumeración Device.Idiom para verificar si estamos en teléfono o tableta:

if (Device.Idiom == TargetIdiom.Tablet)
{

}
else
{

}

La enumeración Device.Idiom cuenta con los siguientes posibles valores:

  • Phone: Indica que estamos en un teléfono. iPhone, iPod touch, Windows Phone y dispositivos Android por debajo de los 600 dips.
  • Tablet: Estamos ante iPad, dispositivos Windows 8.1 o dispositivos Android por encima de los 600 dips.
  • Desktop: Valor que obtenemos en aplicaciones UWP.
  • Unsupported: No soportado.

La clase Device es muy importante en Xamarin.Forms ya que nos permite acceder a una serie de propiedades y métodos con el objetivo de personalizar la aplicación según dispositivo y plataforma. Además de permitirnos detectar el tipo de dispositivo, podemos detectar la plataforma gracias a la enumeración Device.OS o personalizar elementos de la interfaz gracias al método Device.OnPlatform entre otras opciones.

De igual forma que la clase Device nos brinda sus opciones desde código C#, tenemos acceso a ellas desde código XAML:

<OnIdiom 
     x:TypeArguments=""                  
     Phone=""                  
     Tablet=""/> 

Utilizando OnIdiom en cualquier elemento que compone el árbol visual, podemos personalizar propiedades del mismo según si estamos ante teléfonos o tabletas.

Adaptando la UI

En nuestra aplicación, podemos adaptar las diferentes vistas añadiendo diferentes estilos, tamaños de fuente, márgenes y espaciado según estamos en teléfonos o tabletas de forma muy sencilla:

<Label              
     Text="{Binding Driver.CompleteName}"             
     TextColor="White"             
     XAlign="Center">              
     <Label.FontSize>                
          <OnIdiom x:TypeArguments="x:Double"                     
               Phone="24"                  
               Tablet="28"/>             
     </Label.FontSize>            
</Label>

En el ejemplo anterior, el texto que utilizamos para mostrar el nombre de un piloto contará con un tamaño de fuente diferente en teléfonos y tabletas, siendo de mayor tamaño en el caso de contar con mayor tamaño de pantalla.

Adaptando recursos

De igual forma, utilizando OnIdiom podemos personalizar los recursos utilizados por teléfonos y tabletas.

<ContentPage.BackgroundImage>
     <OnIdiom x:TypeArguments="x:String"                  
     Phone="Splash.jpg"                  
     Tablet="Splash@2x.jpg"/>  
</ContentPage.BackgroundImage>

Adaptando la navegación

Poder detectar si estamos ante teléfono o tableta y adaptar los elementos visuales en función de ello esta genial. Podremos continuar compartiendo no solo la lógica sino las vistas de la aplicación añadiendo de forma sencilla cambios por tipo de dispositivo. Sin embargo, la exigencia de los usuarios móviles con la madurez del mercado móvil actual, hace que no sea siempre suficiente. Los usuarios actuales estan ya acostumbrados a experiencias adaptadas y de calidad para cada uno de sus dispositivos. En el caso específico de nuestra aplicación, un listado de pilotos sin aprovechar gran parte del ancho de la pantalla navegando a una vista de detalles, no es la mejor experiencia posible en tabletas.

Ante estos casos, podemos crear vistas específicas personalizadas para tabletas. Para tabletas creamos una nueva vista de tipo maestro-detalle que nos permitirá mostrar el listado de pilotos con su información de detalle a la vez, algo mucho más adaptado y apropiado en tabletas.

public class DriverListTabletView : MasterDetailPage    
{        
     private object Parameter { get; set; }
        
     public DriverListTabletView(object parameter)      
     {
            Title = "Drivers";

            Parameter = parameter;
            Master = new DriverListView(null);

            Detail = new ContentPage
            {
                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    HorizontalOptions = LayoutOptions.Center,
                    Children =
                    {
                        new Label
                        {
                            Text = "Select a Driver",
                            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
                        }
                    }
                }
            };
                           
            ((DriverListView)Master).ItemSelected = (driver) =>
            {
                Detail = new DriverDetailView(driver);

                if (Device.OS != TargetPlatform.Windows)
                    IsPresented = false;

            };

            IsPresented = true;
        }
}

El contenido de Master será la vista del listado de pilotos, mientras que el contenido de Detail será la vista de detalles de un piloto. De esta forma, ofrecemos la mejor experiencia posible en cada tipo de dispositivo pero reutilizando de nuevo, como objetivo siempre firme al utilizar Xamarin.Forms, la mayor cantidad de código posible.

Para modificar el flujo de navegación hacia la vista detalles del piloto utilizando exactamente la misma vista, modificamos la ViewModel del listado de pilotos añadiendo una Action para propagar el evento de selección hacia la nueva vista específica para tabletas.

Utilizando Device.Idiom verificamos si estamos ante teléfono o tableta y modificamos el flujo de navegación en consecuencia:

if (Device.Idiom == TargetIdiom.Tablet || Device.Idiom == TargetIdiom.Desktop)
     Detail = new NavigationPage(new DriverListTabletView(null));
else
     Detail = new NavigationPage(new DriverListView(null));

El resultado:

App Xamarin.Forms adaptada a tabletas
App Xamarin.Forms adaptada a tabletas

Tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

[Xamarin.Forms] Utilizando Messaging Center

Mail Next-WFIntroducción

En el desarrollo de aplicaciones móviles multiplataforma con Xamarin es habitual utilizar el patrón MVVM para separar la vista de la lógica de negocio de la aplicación. De esta forma, podemos conseguir objetivos claves fundamentales como:

  • Nos permite dividir el trabajo de manera muy sencilla (diseñadores – desarrolladores)
  • El mantenimiento es más sencillo.
  • Permite realizar Test a nuestro código.
  • Permite una más fácil reutilización de código.
  • Compartir más código.

Xamarin.Forms incluye un completo sistema de enlace a datos y servicio de dependencias que nos permite realizar una completa implementación del patrón con facilidad. Sin embargo, en ocasiones, necesitamos ciertas «piezas» que nos permitan solucionar problemas existentes manteniendo la arquitectura intacta. En ocasiones realizamos cambios en un elemento de una vista que afecta a otro elemento correspondiente de otra. En este caso, debemos notificar de una viewmodel a otra del cambio.

¿Cómo lo hacemos?

Mensajes

Si has desarrollado previamente utilizando el patrón MVVM utilizando (o no) un framework posiblemente hayas utilizado lo que se conoce como sistema de mensajes. Basicamente la mensajería de basa en el patrón de diseño publish/subscribe. Contamos con tres grandes protagonistas:

  • Mensajes: Información a enviar normalmente relacionada con la lógica de negocio.
  • Publicadores: Cuando un evento ocurre, ya sea un simple click de un botón o una lógica compleja, los publicadores toman la información a enviar y publican el mensaje.
  • Subscriptores: En el lado opuesto, tenemos a los subscriptores que esperan la publicación de un mensaje de un tipo específico para captarlo con toda la información enviada y actuar en consecuencia.

Messaging Center

Xamarin.Forms cuenta con MessagingCenter para permitir la comunicación entre viewmodels u otros componentes sin que tengan que tener referencias entre ambos utilizando el patrón publish/subscribe.

Para probar MessagingCenter vamos a crear una aplicación Xamarin.Forms sencilla donde tendremos dos vistas. La primera vista mostrará un mensaje y un botón además de suscribirse a un mensaje de cambio. El mensaje se modificará utilizando MessagingCenter mientras que el botón permitirá navegar a la segunda vista. Al navegar a la segunda vista se publicará el mensaje de modo que, al regresar a la primera vista el mensaje será modificado.

Definimos la interfaz de la primera vista:

<StackLayout Padding="10" Spacing="10">
     <Label Text="{Binding Info}" />
     <Button 
          Text="Navigate to Second View"
          Command="{Binding NavigateCommand}"/>
</StackLayout>

El resultado:

Nuestra interfaz
Nuestra interfaz

En la viewmodel correspondiente a la vista definimos la propiedad que utilizaremos para mostrar el mensaje:

public string Info
{
     get { return _info; }
     set
     {
          _info = value;
          RaisePropertyChanged();
     }
}

Y el comando que permitirá la navegación a la segunda vista:

private ICommand _navigateCommand;

public ICommand NavigateCommand
{
     get { return _navigateCommand = _navigateCommand ?? new DelegateCommand(NavigateCommandExecute); }
}

public void NavigateCommandExecute()
{
     _navigationService.NavigateTo<SecondViewModel>();
}

En la primera vista vamos a suscribirnos a un mensaje. En Xamarin.Forms contamos con MessagingCenter que cuenta con dos partes fundamentales:

  • Suscripción (Subscribe): Se suscribe a un mensaje concreto para lanzar una acción.
  • Envío (Send): Publica un mensaje para ser captado por suscriptores. Si no existiese ningún subscriptor, el mensaje es ignorado.

La clase MessagingCenter es una clase estática que cuenta con varias sobrecargas del los métodos Subscribe y Send.

Podemos subscribirnos a un mensaje simple con una cadena:

Xamarin.Forms.MessagingCenter.Subscribe<FirstViewModel>(this, "Change", (sender) =>
{
     Info = "Changed from Messaging Center";
});

La viewmodel de la primera vista se subscribe a un mensaje de tipo string con el mensaje «Change».

Navegamos a la segunda vista:

Segunda vista
Segunda vista

En la viewmodel de la segunda vista procedemos a enviar un mensaje de tipo cadena con el valor «Change»:

Xamarin.Forms.MessagingCenter.Send(App.Locator.FirstViewModel, "Change");

Al regresar a la vista anterior, el mensaje ha cambiado con la lógica ejecutada en la subscripción del mensaje:

Mensaje recibido
Mensaje recibido

Sencillo, ¿cierto?

Pasar parámetros como argumento

Podemos pasar un argumento como parámetro del método Send:

MessagingCenter.Send(App.Locator.FirstViewModel, "Change", "Argument");

En la subscripción podemos capturar el parámetro de forma sencilla:

MessagingCenter.Subscribe<FirstViewModel>(this, "Change", (sender, arg) => {
    // Acceso a 'arg' para obtener el parametero
});

Podéis encontrar en GitHub el ejemplo de este artículo:

Ver GitHub

Recordad que cualquier duda o sugerencia la podéis dejar en los comentarios del blog.

Más información