[Preview] Primer vistazo a Xamarin.Forms CollectionView

Introducción

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

Xamarin.Forms CollectionView

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

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

Primeros pasos

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

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

Layout básico

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

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

El resultado:

Layout básico

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

Listas horizontales

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

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

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

El resultado:

Listas horizontales

Carousel

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

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

El resultado:

Carousel

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

Grid

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

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

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

Grid Layout

Vista cuando no hay contenido

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

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

El resultado:

Sin contenido

Sencillo, ¿verdad?.

Tienes el ejemplo disponible en GitHub:

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

Más información

Anuncios

[Preview] Primer vistazo a Xamarin.Forms Visual

Introducción

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

Xamarin.Forms Visual

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

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

NOTA: Utilizando Visual seguimos utilizando controles 100% nativos.

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

<ContentPage 
     Visual="Material">

</ContentPage>

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

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

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

  • Button
  • Entry
  • Frame
  • ProgressBar

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

Forms.SetFlags("Visual_Experimental");

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

NOTA: Visual requiere API 29 para funcionar en Android.

Veamos un ejemplo:

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

El resultado:

Tienes el ejemplo disponible en GitHub:

Ver GitHub

Más información

[Material] Monkey Conf 2018

El evento

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

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

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

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

Sponsors, gracias!

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

Muchas gracias!

El material

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

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

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

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

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

Ver GitHub

Más información

Xamarin.Forms Compiled Bindings

Introducción

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

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

Utilizando Bindings compilados

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

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

[assembly: XamlCompilation (XamlCompilationOptions.Compile)]

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

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

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

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

Mezclando Bindings compilados con clásicos

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

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

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

Rendimiento

Los bindings compilados mejoran el rendimiento:

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

Entonces, ¿ofrecen mejor rendimiento los bindings compilados?

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

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

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Más información

[Evento] Monkey Conf 2018

El evento

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

Monkey Conf 2018

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

La fecha

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

¿Te apuntas?

NOTA: Las entradas del evento son gratuitas pero limitadas!

El lugar

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

Paseo de la Castellana, 280, 28046 Madrid, Madrid

Liferay

Call 4 Papers

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

Más información

[Xamarin.Forms] Utilizando TitleView

Introducción

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

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

TitleView

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

Cabecera personalizada

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

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

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

El resultado:

Cabecera personalizada!

Comandos

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

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

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

Gestos

Barra de búsqueda

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

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

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

El resultado:

Búsqueda

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Limitaciones o problemas conocidos actuales

Entre el listado de limitaciones actuales encontramos:

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

Más información

[Material] Analizando interfaces de usuario avanzadas con Xamarin.Forms

El evento

El pasado 26 de Septiembre, teníamos en SVQXDG un divertido evento donde abriendo debate e intercambiando ideas algunos de los ejemplos revisamos opciones disponibles para conseguir interfaces atractivas con Xamarin.Forms. Vimos opciones como efectos, Custom Renderers, SkiaSharp, VisualStateManager, etc.

El material

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

En cuanto a ejemplos, revisamos muchos ejemplos revisando UI y opciones en cada uno de ellos.

My Trip Countdown

Sencillo contador atrás hacia el momento de una fecha (viaje).

My Trip Countdown

Las claves:

  • Uso de SkiaSharp para crear progreso circularcon degradado.
  • Gestión de imágenes con efectos (circular).
  • Botón con degradado.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Pulse Music

Interfaz de un reproductor de música.

Pulse Music

Las claves:

  • Uso de SkiaSharp para crear progreso circular.
  • Animaciones infinitas.
  • Gestión de imágenes con efectos (circular).

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Walkthrough

Creación de un Walkthrough con diferentes pasos animados.

Walkthrough

Las claves:

  • Uso de Carousel.
  • Animaciones con Lottie.
  • API de animaciones de Xamarin.Forms.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Netflix

Ejemplo donde se replica la interfaz básica de Netflix.

Vista principal en Android

La claves de este ejemplo:

  • Navegación personalizada (logo, transparencias, etc.).
  • Listados horizontales.
  • Parallax.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Movies

El último ejemplo que revisamos. Aplicación utilizando la API de TheMovieDB.

Movies

La claves de este ejemplo:

  • Crear aplicaciones para Linux y WPF utilizando Xamarin.Forms.
  • Personalizar estilos para Linux y WPF.
  • Aplicar temas GTK.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Más información

Primer vistazo a Xamarin.Forms gui.cs Backend

Introducción

Las aplicaciones de consola son geniales!. Probablemente, has realizado alguna aplicación de consola con alguna pequeña (o gran) herramienta.Tener una aplicación de consola tiene ventajas: liviana, multiplataforma, rápida, etc.

¿Y si pudiesemos realizar aplicaciones de consola con Xamarin.Forms?.

gui.cs

Estamos ante un Toolkit de UI para .NET, .NET Core y Mono que permite crear apliaciones de consola (si, con interfaz!) para Linux, macOS y Windows. Creado por Miguel de Icaza.

gui.cs

El Toolkit cuenta con una variedad de controles:

Añade soporte a colores, reescalado de pantalla, eventos, async, etc. A nivel de gestión de vistas es bastante similar a otros frameworks de UI como GTK# .

Conceptos básicos

gui.cs cuenta on Application.Run, que facilita un bucle principal donde:

  • Procesar eventos de teclado.
  • Gestiona el foco.
  • Redibuja áreas de la pantalla.
  • Timers.
  • Etc.

Cada elemento visual, hereda de la clase View. Toda View cuenta con propiedades X, Y, Height y Width para la gestión de tamaño y posición. Todo se pone más interesante al poder realizar composición de Views.

¿Y por qué Xamarin.Forms?

Buena pregunta. El framework ya permite grandes posibilidades, es sencillo de usar, así que, ¿por qué?.

EL origen

Why not?

Xamarin.Forms cada vez llega a más plataformas tras los backends de WPF y GTK, además de seguir aumentando en posibilidades. Ya había utilizada gui.cs para herramientas y pruebas, vi un tweet, nació un reto personal y voila. ¿Por qué no añadir la posibilidad de crear aplicaciones de consola con Xamarin.Forms?.

Backend gui.cs

Disponible en GitHub y en NuGet, nace el backend de Xamarin.Forms de gui.cs.

NOTA: Todos los ejemplos anteriores estan realizados con Xamarin.Forms.

Actualmente con soporte a:

  • ContentPage
  • Layouts
  • Label
  • Button
  • Editor
  • Entry
  • ListView
  • ProgressBar
  • Switch

Paulatinamente se añadirá soporte a otras características y controles.

¿Cómo lo uso?

Partimos de una aplicación de consola. Tras crear la aplicación, añadimos el paquete NuGet Terminal.Gui.Forms:

Terminal.Gui.Forms

Se encarga de añadir las referencias necesarias tanto a Terminal.Gui como a Xamarin.Forms.

Creamos un Application de Xamarin.Forms:

public class App : Xamarin.Forms.Application
{
     public App()
     {
          MainPage = new MainView();
     }
}

Se encargará de iniciar y establecer la página inicial. La página inicial, creada con XAML:

<StackLayout>
     <Grid 
          Padding="10, 10, 10, 10">
     <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
     </Grid.RowDefinitions>
     <Grid.ColumnDefinitions>
          <ColumnDefinition Width="60" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="100" />
     </Grid.ColumnDefinitions>
     <Label 
          Text="Search by Zip Code" 
          Grid.Row="0" 
          Grid.Column="0" 
          Grid.ColumnSpan="3"
          TextColor="White"
          Margin="0, 6"/>
     <Label 
          Text="Zip Code:" 
          Grid.Row="1"
          Grid.Column="0"
          Style="{StaticResource LabelStyle}"
          TextColor="#C0C0C0" />
     <Entry
          Grid.Row="1"
          Grid.Column="1"
          Text="{Binding ZipCode, Mode=TwoWay}"
          Margin="5, 0" />
     <Button 
          Text="Get Weather" 
          Grid.Row="1" 
          Grid.Column="2"
          Command="{Binding WeatherCommand}"/>
     </Grid>
     <StackLayout
          Padding="10, 10, 10, 10">
          <Label 
               Text="Location" 
               Style="{StaticResource LabelStyle}" />
          <Label 
               Text="{Binding Weather.Title}"
               Style="{StaticResource FieldStyle}" />
          <Label 
               Text="Temperature"
               Style="{StaticResource LabelStyle}" />
          <Label 
               Text="{Binding Weather.Temperature}" 
               Style="{StaticResource FieldStyle}" />
          <Label
               Text="Wind Speed"
               Style="{StaticResource LabelStyle}" />
          <Label 
               Text="{Binding Weather.Wind}"
               Style="{StaticResource FieldStyle}" />
          <Label 
               Text="Humidity" 
               Style="{StaticResource LabelStyle}" />
          <Label
               Text="{Binding Weather.Humidity}"
               Style="{StaticResource FieldStyle}" />
          <Label 
               Text="Visibility" 
               Style="{StaticResource LabelStyle}" />
          <Label 
               Text="{Binding Weather.Visibility}"
               Style="{StaticResource FieldStyle}" />
          <Label 
               Text="Time of Sunrise" 
               Style="{StaticResource LabelStyle}" />
          <Label
               Text="{Binding Weather.Sunrise}"
               Style="{StaticResource FieldStyle}" />
          <Label
               Text="Time of Sunset" 
               Style="{StaticResource LabelStyle}" />
          <Label 
               Text="{Binding Weather.Sunset}"
               Style="{StaticResource FieldStyle}" />
     </StackLayout>
</StackLayout>

Hacemos uso de:

  • Diferentes Layouts
  • Diferentes controles
  • Enlace a datos
  • Estilos
  • Etc

La página cuenta con una ViewModel enlazada que se encarga de usar un servicio que accederá a información de OpenWeatherMap para informar de datos climatológicos dado un código postal.

Sólo nos falta, en la clase Program, inicializar Terminal.Gui, XamarinForms; cargar nuestra aplicación; y ejecutar la misma:

public class Program
{
     public static void Main()
     {
          Terminal.Gui.Application.Init();
          Forms.Init();
          var app = new App();
          var window = new FormsWindow("WeatherApp");
          window.LoadApplication(app);
          Terminal.Gui.Application.Run();
     }
}

Sencillo, ¿verdad?. Veamos el resultado:

WeatherApp

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Recuerda, es una Preview…

Estamos ante la primera Preview con un soporte limitado de guis.cs y de Xamarin.Forms. Sin embargo, hay algunas características aun no disponibles:

  • Frame
  • Menus
  • ScrollView
  • Etc

Más información

Channel 9: Retro Computing with .NET

[Xamarin.Forms] Nueva extensión de marcado para OnPlatform y OnIdiom

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

A pesar de definir la interfaz de usuario una única vez para todas las plataformas, tenemos la posibilidad de realizar personalizaciones y adaptaciones para ofrecer la mejor experiencia posible en cada una de las plataformas soportadas.

La clase Device

La clase Device sin duda alguna es una de las claves a la hora de personalizar la interfaz de usuario por plataforma. Esta clase contiene diversas propiedades y métodos para personalizar la UI y la funcionalidad en base a la plataforma.

Hasta ahora…

Dentro de la clase Device, la propiedad OS permitía identificar la plataforma en la que se ejecuta la aplicación. La extensión demarcado OnPlatform permite personalizar la interfaz por plataforma. La extensión OnPlatform esta soportada por la clase OnPlatformExtension (se permite la abreviatura OnPlatform desde XAML) que define las siguientes propiedades:

  • Default: Representa el valor por defecto que aplica a todas las plataformas.
  • Android: Valor aplicado en Android.
  • GTK: Valor aplicado en plataformas GTK.
  • iOS: Valor aplicado en iOS.
  • macOS: Valor aplicado en macOS.
  • Tizen: Valor aplicado en plataformas Tizen.
  • UWP: Valor aplicado en Universal Windows Platform
  • WPF: Valor aplicado en la plataforma Windows Presentation Foundation.

Hasta ahora, el uso de OnPlatform era:

<BoxView>
     <BoxView.Color>
          <OnPlatform x:TypeArguments="Color">
               <On Platform="Android" Value="Green" />
               <On Platform="iOS" Value="Blue" />
               <On Platform="UWP" Value="Orange" />
          </OnPlatform>
     </BoxView.Color>
</BoxView>

La extensión de marcado OnIdiom permite realizar personalizaciones de la apariencia basadas en el tipo de dispositivo donde corre la App. Soportado por la clase OnIdiomExtension define las siguientes propiedades:

  • Default: Valor por defecto, aplicado a todos los dispositivos.
  • Phone: Valor aplicado a teléfonos.
  • Tablet: Valor aplicado a tabletas.
  • Desktop: Aplicado a plataformas de escritorio.
  • TV: Valor aplicado a plataformas TV.
  • Watch: En este caso, el valor se aplica a plataformas Watch.

Donde, el uso de OnIdiom hasta ahora era:

<BoxView>
     <BoxView.Color>
          <OnIdiom x:TypeArguments="Color">
               <OnIdiom.Phone>Green</OnIdiom.Phone>
               <OnIdiom.Tablet>Blue</OnIdiom.Tablet>
               <OnIdiom.Desktop>Orange</OnIdiom.Desktop>
          </OnIdiom>
     </BoxView.Color>
</BoxView>

Hasta ahora…

Llega nueva extensión de marcado con Xamarin.Forms 3.2

Con Xamarin.Forms 3.2 llega una nueva versión de extensión de marcado para OnPlatform y OnIdiom.

Veamos su uso con OnPlatform:

<BoxView 
     Color="{OnPlatform Red, Android=Green, iOS=Blue, UWP=Orange}"/>

Y con OnIdiom:

<BoxView 
     Color="{OnIdiom Red, Phone=Green, Tablet=Blue, Desktop=Orange}" />

Como podemos ver, se simplifica la verbosidad para conseguir el mismo resultado.

Puedes encontrar ejemplo en GitHub:

Ver GitHubY a ti, ¿qué te parece la novedad?.

Más información

[Xamarin.Forms] Efecto para personalizar la StatusBar

Introducción

La StatusBar es un área importante de cara al usuario final. Disponible para mostrar información importante relacionada con el estado del sistema (hora, batería, red, etc.) además de notificaciones de otras aplicaciones.

StatusBar

Al desarrollar aplicaciones móviles, entre los objetivos, debemos conseguir un estilo único y uniforme. Para conseguirlo, en ocasiones será necesario modificar el aspecto de la StatusBar o incluso cambiarlo de forma uniforme para adaptarla a diferentes páginas de nuestra aplicación.

¿Cómo personalizamos la StatusBar?. En este artículo vamos a crear un efecto de Xamarin.Forms para personalizar la StatusBar en Android, iOS y en UWP.

Efectos

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.

Crear un efecto

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

  1. Crear en la libería .NET Standard 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.

Definición del efecto

Comenzamos con la definición del efecto. Creamos una clase que hereda de RoutingEffect:

public class StatusBarEffect : RoutingEffect
{
     public Color BackgroundColor { get; set; }

     public StatusBarEffect() : base("Xamarin.StatusBarEffect")
     {

     }
}

Fíjate que definimos una propiedad de tipo Color llamada BackgroundColor que nos permitirá establecer el color de la StatusBar.

Android

En Android, accedemos a la Window de la actividad, para modificar el color de la StatusBar utilizando el método SetStatusBarColor:

var statusBarEffect = (StatusBarXamarinForms.Effects.StatusBarEffect)Element.Effects.FirstOrDefault(e => e is StatusBarXamarinForms.Effects.StatusBarEffect);

if (statusBarEffect != null)
{
     var backgroundColor = statusBarEffect.BackgroundColor.ToAndroid();
     Window currentWindow = GetCurrentWindow();
     currentWindow.SetStatusBarColor(backgroundColor);
}

Convertimos el color de Xamarin.Forms a Android utilizando la extensión ToAndroid. Mientras que, para tener acceso de forma sencilla a la actividad actual, usamos el plugin CurrentActivityPlugin:

var window = CrossCurrentActivity.Current.Activity.Window;

iOS

En iOS, accedemos a la StatusBar, y le establecemos el color de fondo utilizando la propiedad BackgroundColor:

if (statusBarEffect != null)
{
     UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
     if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
     {
          statusBar.BackgroundColor = statusBarEffect.BackgroundColor.ToUIColor();
     }
}

En este caso, el color lo convertimos a un UIColor con la extensión ToUIColor.

UWP

En el caso de UWP, contemplamos dos posibilidades:

NOTA: Para tener acceso a estas APIs es necesario añadir como referencia a las extensiones UWP correspondientes.

Comenzamos por el uso de la TitleBar:

// Desktop Customization
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView"))
{
     var titleBar = ApplicationView.GetForCurrentView().TitleBar;
     if (titleBar != null)
     {
          titleBar.BackgroundColor = statusBackgroundColor;
          titleBar.ButtonBackgroundColor = statusBackgroundColor;
     }
}

Accedemos a la misma y establecemos el color de fondo.

En el caso de StatusBar es bastante similar:

// Mobile Customization
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
     var statusBar = StatusBar.GetForCurrentView();
     if (statusBar != null)
     {
          statusBar.BackgroundOpacity = 1;
          statusBar.BackgroundColor = statusBackgroundColor;
     }
}

Sencillo, ¿verdad?.

Utilizando el efecto

Llega el momento de utilizar nuestro efecto!. Comenzamos añadiendo el namespace correspondiente en XAML:

xmlns:local="clr-namespace:StatusBarXamarinForms.Effects"

Y utilizamos el efecto:

<ContentPage.Effects>
<local:StatusBarEffect 
     BackgroundColor="Red"/>
</ContentPage.Effects>

El resultado:

Podemos añadir el efecto desde código C# y nos da la posibilidad de moficar la StatusBar programáticamente de forma sencilla.

Puedes encontrar el ejemplo en GitHub:

Ver GitHub

Más información