Artykuł

freeimages.com freeimages.com
lip 18 2016
0

Xamarin.Forms - pierwsza aplikacja

W poprzednim wpisie na temat Xamarina, zrobiłem małe wprowadzenie teoretyczne do tej technologii. Przedstawiłem podstawowe założenia oraz dostępne warianty użycia tego rozwiązania.

Jeśli uważasz, że wybór technologii jaką jest Xamarin był sam w sobie trudną decyzję, to mam niestety złą wiadomość. Już na starcie trzeba podjąć kolejną i to równie ważną. Którego podejścia użyć - Forms czy Native?

W poprzednim poście przedstawiłem podstawowe założenia obu z nich. W wielkim skrócie - Forms zapewnią większą reużywalność kodu kosztem elementów specyficznych dla wspieranych platform. Podejście native z kolei, pozwala na tworzenie layoutów z użyciem elementów i technologii charakterystycznych dla wspieranych platform, co oczywiście wiąże się z większym nakładem kosztów. Wybór więc tak naprawdę zależy od potrzeb.

Warto jednak dodać, że wybór podejścia Forms niekoniecznie oznacza całkowite odcięcie od podejścia native. Oba rozwiązania można mieszać, z tym że w praktyce lepiej funkcjonują wstawki native w części Forms aniżeli odwrotnie. Z tego też powodu w dzisiejszym tekście skupimy się na podejściu opartym o formatki.

Portable czy Shared?

Decydując się na Xamarin.Forms, musimy podjąć kolejną decyzję (dużo ich w tej technologii:) - czy będziemy używać podejścia Shared, czy też biblioteki Portable? Oba rozwiązania mają swoje wady i zalety. Pierwsze z nich zapewnia większą przenaszalność kodu, ale utrudnia tworzenie rozwiązań specyficznych dla platform. Drugie z podejść pozwala na tworzenie kodu warunkowego dla różnych systemów przy pomocy dyrektyw preprocesora, co z jednej strony może uprościć development, z drugiej zaś mocno zaciemnić kod.

Osobiście jestem zwolennikiem pierwszej opcji. Zapewnia ona jasny podział kodu w aplikacji, zwiększa przenaszalność tworzonych rozwiązań, a także pozwala na budowanie bibliotek z kodem specyficznym dla określonych systemów. Taki kod może być później załadowany za pomocą dependency injection.

Oprogramowanie

Tworząc nowy projekt, należy pamiętać o tym, że programowanie rozwiązań Microsoftowych, nie jest możliwe z poziomu Xamarin Studio w systemie OS X (więcej na ten temat pisałem tutaj, w akapicie oprogramowanie). Dlatego też jeśli dysponujecie tylko systemem OS X, to Wasz development ograniczy się do Androida oraz iOS. Na Windows można zrobić wszystko, ale potrzebny jest komputer z systemem od Apple znajdujący się w sieci lokalnej, by możliwa była kompilacja aplikacji pisanych na iOS.

Tworzenie projektu w Visual Studio

Wszystkie dostępne opcje tworzenia nowych projektów, znajdziecie na dialogu tworzenia nowej solucji. Tak jak wcześniej wspominałem, na tym etapie trzeba dokonać kilka wyborów. W tym przykładzie utworzymy projekt Xamarin.Forms w wersji portable:

Proces tworzenia solucji może zająć dłuższą chwilę, ponieważ standardowo tworzonych jest do 5 projektów systemowych (liczba uzależniona jest od konfiguracji systemu) oraz jeden portable (lub ewentualnie część shared).

Po zakończeniu procesu tworzenia solucji, projekt dla każdego OSu będzie gotowy do kompilacji.

Uruchamianie projektów odbywa się w standardowy sposób. Należy wybrać emulator, bądź też fizyczne urządzenie z listy rozwijanej, a następnie po prostu wystartować projekt. Oczywiście wcześniej należy się upewnić, że cała instalacja została przeprowadzona poprawnie.

Na poniższym screenie widać uruchomienie przykładowej aplikacji na emulatorze dla Androida.

Aplikacja w aplikacji

Punktem startu dla Xamarin.Forms jest klasa App, która dziedziczy ze zdefiniowanej przez twórców Xamarina klasy Application. Po utworzeniu standardowego projektu w Visual Studio, jej kod będzie wyglądał następująco:

public class App : Application
{
    public App()
    {
        // The root page of your application
        MainPage = new ContentPage
        {
            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.Center,
                Children = {
                    new Label {
                        HorizontalTextAlignment = TextAlignment.Center,
                        Text = "Welcome to Xamarin Forms!"
                    }
                }
            }
        };
    }

    protected override void OnStart()
    {
        // Handle when your app starts
    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

W konstruktorze utworzona zostaje domyślna strona główna, wyświetlająca etykietę w stylu Hello World. Xamarin.Forms pozwala również na tworzenie stron za pomocą języka znaczników XAML.

Oprócz tego w nasze ręce oddano trzy metody, które odpowiadają kolejno za zdarzenie:

  • Uruchomienia aplikacji
  • Uśpienia aplikacji - metoda ta jest wywoływana w momencie gdy aplikacja w jakikolwiek sposób zniknie z pierwszego planu. Przy okazji warto zaznaczyć, że system może zamknąć aplikację, która pracuje w tle. Warto to uwzględnić w swoich projektach
  • Wznowienia aplikacji - zdarzenie to zawsze występuje po zdarzeniu OnSleep. Wystarczy więc np. uruchomić menadżer zadań w Androidzie i później ponownie wybrać naszą aplikację, by wygenerować kolejno sekwencję OnSleep - OnResume

Jeśli nie mamy żadnego kodu do dowolnej z powyższych metod, to nie ma konieczności przeciążania metod domyślnych. Klasa Application, która jest dla nas bazą, deklaruje te metody jako virtual.

Cały czas pisałem o tym jakby klasa App była czymś na kształt klasy Program w aplikacjach konsolowych i tak w pewnym sensie jest.. choć nie do końca. Klasa App jest punktem startu dla Xamarin.Forms, ale tak naprawdę program startuje w innym miejscu, które uzależnione jest od systemu:

  • W Androidzie jest to MainActivity:
    [Activity(Label = "FormsSample", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
    
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
  • W iOS jest jest to klasa AppDelegate:
    // The UIApplicationDelegate for the application. This class is responsible for launching the 
    // User Interface of the application, as well as listening (and optionally responding) to 
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
    
            return base.FinishedLaunching(app, options);
        }
    }
  • W UWP jest to strona MainPage (podobnie zresztą jak w pozostałych rozwiązaniach MS):
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
    
            LoadApplication(new FormsSample.App());
        }
    }

Jak nietrudno zauważyć, w pewnym sensie uruchamiamy tutaj aplikację w aplikacji wykorzystując standardowe punkty wejścia charakterystyczne dla każdego z obsługiwanych systemów. I to jest właśnie wielki sekret skrywany w podejściu Xamarin.Forms:)

W kolejnych wpisach postaram się Wam przedstawić kolejne ciekawe aspekty tego rozwiązania.

Data ostatniej modyfikacji: 05.08.2016, 23:46.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus