Introducció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:

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:

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:

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:
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 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 Blog: Adding Bindable Native Views Directly to XAML