Introduciendo Xamarin.Forms en Xamarin nativo

fernando-avatar-200px.png

Escrito por
Senior Mobile Developer 12 julio, 2017

Cuando nos planteamos un nuevo proyecto siempre surge la misma pregunta:

¿Usamos Xamarin.Forms o Xamarin nativo? 

Xamarin Forms permite crear las pantallas una vez y utilizarlas en todas las plataformas, mientras que con Xamarin nativo es necesario crear las pantallas de manera independiente. 

 

No obstante, el rendimiento de Xamarin nativo es mucho más alto que el de Forms y podría ser imprescindible en apps con mucho consumo de recursos, o para aquellas que necesitan funcionar lo más rápido posible. 

Por esto surge Xamarin.Forms 3.0, el cual incluye la capacidad de utilizar pantallas de Xamarin.Forms en Xamarin nativo. Esto nos proporciona muchas de las ventajas de la reutilización de Xamarin.Forms sin perder el rendimiento de Xamarin nativo. 


Implementación en Android

  1. Primero crearemos un proyecto Xamarin nativo usando el template y agregaremos la versión 3.0 de Xamarin.Forms desde nuget
  2. En la PCL crearemos un ContentPage.xaml con su correspondiente fichero de código (Para el ejemplo haremos un sencillo lector RSS) 
  3. Crearemos un layout con una lista para mostrar las entradas: 

    <?xml version="1.0" encoding="utf-8" ?>

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

                 BackgroundColor="White"

                 x:Class="App1.MainPage">

        <ListView

                BackgroundColor="White"

                ItemTapped="listView_ItemTapped"

                ItemsSource="{Binding Items}">

            <ListView.ItemTemplate>

                <DataTemplate>

                    <ViewCell>

                        <StackLayout Orientation="Vertical">

                            <Label Text="{Binding Title}" FontSize="Medium"  TextColor="Black" LineBreakMode="NoWrap" Margin="10,10,10,10"/>

                        </StackLayout>

                    </ViewCell>

                </DataTemplate>

            </ListView.ItemTemplate>

        </ListView>

    </ContentPage>

     

  4. Y después, añadiremos el código de nuestro lector RSS al código asociado al XAML que acabamos de crear: 

    public partial class MainPage : ContentPage

        {

            private ObservableCollection<RssItem> _items;

     

            public ObservableCollection<RssItem> Items

            {

                get { return _items; }

                set {

                        _items = value;

                        OnPropertyChanged("Items");

                    }

            }

     

            public MainPage()

            {

                InitializeComponent();

    this.BindingContext = this;

                this.Title = "StackOverflow Feed";

     

                GetFeed();

            }

     

            private async void GetFeed()

            {

    Items = new ObservableCollection<RssItem>(await GetItems("https://stackoverflow.com/feeds/tag/xamarin-forms"));

            }

     

            public async Task<IEnumerable<RssItem>> GetItems(string feedUrl)

            {

                    using (var client = new HttpClient())

                    {

                        var xmlFeed = await client.GetStringAsync(feedUrl);

                        var doc = XDocument.Parse(xmlFeed);

                        XNamespace dc = "http://www.w3.org/2005/Atom";

     

                        var rawItems = new List<XElement>(doc.Descendants(dc + "entry"));

     

                        var items = (from item in rawItems

                                     select new RssItem

                                     {

                                         Title = item.Element(dc + "title").Value,

                                         Link = item.Element(dc + "id").Value

                                     });

     

                    var resultList = new List<RssItem>(items);

     

                    return resultList;

                    }

            }

     

            private void listView_ItemTapped(object sender, ItemTappedEventArgs e)

            {

                Device.OpenUri(new Uri(((RssItem)e.Item).Link));

            }

        }

     

    En este caso hemos utilzado un Binding para enlazar con los datos de la lista, al utilizar un ObservableCollection y OnPropertyChanged, conseguimos que la lista refleje automáticamente los cambios. 

    Además, también hemos implementado el click en los elementos que nos lanzarán al navegador para ver el post completo. 

  5. A continuación, para poder ver el fragment dentro de la activity, necesitamos un contenedor. Lo añadiremos al layout que usaremos en la Activity de Android: 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        >

     

      <FrameLayout

          android:layout_width="fill_parent"

          android:layout_height="fill_parent"

          android:id="@+id/fragment_frame_layout"/>

    </LinearLayout>

  6. Una vez tenemos el layout de la activity preparado para mostrar el fragment creado por la página de Xamarin.Forms, solo nos quedan dos pasos: 
  7. Iniciamos Xamarin.Forms llamando a Init()
  8. Instanciamos la página previamente creada en la PCL y utilizamos el método CreateFragment() que nos devuelve un fragment estándar de Android. 
  9. Posteriormente, añadiremos el fragment al contenedor de la forma estándar de Android: 

    public class MainActivity : Activity

           {

                 protected override void OnCreate (Bundle bundle)

                 {

                        base.OnCreate (bundle);

     

                        SetContentView (Resource.Layout.Main);

     

                Forms.Init(this,bundle);

     

                var fragment = new MainPage().CreateFragment(this);

                var ft = FragmentManager.BeginTransaction();

     

                ft.Replace(Resource.Id.fragment_frame_layout, fragment, "main");

                ft.Commit();

            }

           }

 

¡Y listo!

Si lo ejecutamos podremos ver cómo aparece una pantalla simple con nuestro label y el texto que le hemos asignado en la página de Xamarin.Forms: 

xamarinforms-4.png

xamarinforms2-1.png

xamarinforms4.png


Implementación en iOS

Partiendo del proyecto anterior, puesto que ya tenemos creada la página de Xamarin.Forms, vamos directamente al proyecto de iOS. 

El proceso es el mismo, con la única diferencia de que en lugar de un Fragment Forms, nos crea un UIViewController que es más similar al Activity en Android. 

Un buen lugar para inicializar Xamarin.Forms en iOS es el método FinishedLaunching de AppDelegate , de esta manera vamos a mostrar nuestro XAML como pantalla principal

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)

        {

            Forms.Init();

 

            var page = new MainPage();

 

            var controller = page.CreateViewController();

 

            this.Window = new UIWindow(UIScreen.MainScreen.Bounds);

 

            this.Window.RootViewController = controller;

 

            this.Window.MakeKeyAndVisible();

 

            return true;

        }

También podríamos mostrar nuestra página navegando de forma normal desde un NavigationController

var page = new MainPage();

            var controller = page.CreateViewController();

            NavigationController.PushViewController(controller, true);

 

 

¡Y listo!

Ya podemos ejecutarlo: 

 

xamarinforms7.png

 


¿Y la cabecera?

Como podéis observar, no tenemos cabecera

Nuestro XAML ocupa totalmente la pantalla. Recordamos que en Android utilizamos un fragment que luego colocábamos en un activity que contiene una cabecera por defecto. 

En el caso de iOS utilizamos un UIViewController, el cual se muestra directamente. 

Teniendo en cuenta esto, tenemos varias opciones para adaptar las UI a cada plataforma. Podríamos utilizar las cabeceras nativas de cada plataforma, y el resto del contenido compartirlo, o bien hacerlo totalmente en XAML. 

Además de la UI de Xamarin.Forms, actualmente también están disponibles DependencyService y MessagingCenter para utilizar en proyectos nativos. 

 

¡Hasta aquí todo por hoy! 

Espero que os haya servido de ayuda este post. 

Y ya sabéis, si tenéis alguna duda, dejadnos un comentario abajo ;)

¡Nos vemos! 

ojo_07 ¿ Te gusta lo que lees? Suscríbete a nuestras newsletters