środa, 7 września 2016

Xamarin.Forms kontra Xamarin odc.1 (toolbar, nawigacja, stylowanie, lokalizacja, ikony aplikacji)

Dobry wieczór, w nowym cyklu tematycznym Xamarin.Forms kontra Xamarin witam serdecznie. Z XAML w Xamarin musiałem się po prostu zmierzyć, to była tylko kwestia czasu.

Z XAML jestem od początku tzn. początku 2005, kiedy były wersje CTP ówczesnego .NET 3.0. Po zachwycie nad WPF miałem wręcz najlepszy dev-okres w czasach Silverlight. Byłem też wielkim entuzjastą Silverlight w Windows Phone 7.x. Z chwilą pojawienia się pierwszego wydania Windows 8 Developer Preview uważnie zapoznałem się z XAML WinRT, śledziłem też rozwój wypadków w Windows Phone 8.x. Na ulepszonym nieco XAML WinRT opierają się z kolei aplikacje uniwersalne XAML w Windows 10.

Z XAML jestem naprawdę długo. Nie chcę popadać w jakąś megalomanię, ale zaczynam chyba skalą czasową doganiać takie osobowości jak Andy Wigley, Charles Petzold, Jessy Liberty czy Pete Brown. Był jeszcze John Papa, ale on na 100% przechcił się na HTML 5, a ja tylko częściowo. Co te osoby dziś wszystkie robią (poza JP)?  Zajmują się platformą Xamarin, a zwłaszcza Xamarin.Forms, który obsługuje XAML. Nie wypadało wręcz tego odpuścić.

Aby nie było zbyt prosto dodam, że mamy doczynienia z kolejna odmiana XAML, z zauważalnymi różnicami w stosunku do wszystkich technologii jakie tutaj dziś wymieniłem. Jakie są to różnice?  A jak ma się to do Xamarin.Android i Xamarin.iOS czy natywnych rozwiązań w oryginale?  To przykładowe pytania, na które będziemy udzielać odpowiedzi. Zrobimy to tworząc jeszcze bardziej kolekcjonerską wersję app-ki z czasów DSP, tym razem o nazwie Light Organ XF / Kolorofon XF (XF od Xamarin Forms!). Nie wiem czemu, ale od początku miałem wizję, że jej kolor będzie w kolorze “różowego złota” . Nawet nadałem jej kryptonim “różowe złoto”. Nie jestem oryginalny, jak wiadomo to jeden z kolorów iPhone (btw dziś zgodnie ze spiskowymi teoriami odbyła się premiera iPhone 7,  jak skończę tego posta wskakuję komentować na twitterze).

Po dość długim wstępie, mogę w końcu powiedzieć zaczynamy!

image

Na razie jesteśmy w fazie początkowej, na github dwa niemal puste ekrany,  póki co na Android i iOS.  Oto jeden z nich:

Screenshot_20160907-205510  IMG_0057

Jak to wygląda w 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"
             xmlns:i18n="clr-namespace:LightOrganApp"
             xmlns:local="clr-namespace:LightOrganApp"
             x:Class="LightOrganApp.MainPage" Title="{i18n:Translate AppName}"
             BackgroundColor="{StaticResource PageBackgroundColor}">
  <ContentPage.ToolbarItems>
    <ToolbarItem Text="{i18n:Translate ActionMediaFiles}" Clicked="OnMediaFilesClicked">     
      <ToolbarItem.Icon>
        <OnPlatform x:TypeArguments="FileImageSource" Android="ic_library_music_white_48dp.png" iOS="Search.png"/>
      </ToolbarItem.Icon>     
    </ToolbarItem>   
  </ContentPage.ToolbarItems> 

</ContentPage>

Zasoby przydatne dla wielu stron zdefiniowałem w App.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="LightOrganApp.App">
  <Application.Resources>
    <ResourceDictionary>
      <Color x:Key="PageBackgroundColor">#ff8a80</Color>
      <Style TargetType="NavigationPage">
        <Setter Property="BackgroundColor" Value="{StaticResource PageBackgroundColor}"/>
        <Setter Property="BarBackgroundColor" Value="#e57373"/>
        <Setter Property="BarTextColor" Value="White"/>
      </Style>     
    </ResourceDictionary>   
  </Application.Resources>
</Application>

A code-behind strony?

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            if (Device.OS == TargetPlatform.Android)
            {
                var toolbarItem = new ToolbarItem(AppResources.ActionSettings, null, () => { }, ToolbarItemOrder.Secondary, 0);
                ToolbarItems.Add(toolbarItem);
            }
        }

        async void OnMediaFilesClicked(object sender, EventArgs e)
        {
            var fileListPage = new FileListPage();
                
            await Navigation.PushAsync(fileListPage);
        }
    }

Strona FileListPage jest póki co pusta, tylko z pustym toolbarem. A teraz uwagi. Będzie ich sporo, pewnie nie dam rady podzielić się wszystkim, co mam w głowie, ale traktuję tego posta tylko jako swoisty skrótowy ekspres z ciekawostkami.

#1  XAML

Mamy XAML z roku 2009. Brawo. XAML-e tworzone od początku przez Microsoft nadal bazują na specyfikacji z 2006 (za wyjątkiem WF). Czemu muszę pisać jawnie ResourceDictionary w Resources?  Czemu mam pisać BackgroundColor zamiast Background?  Andy Wigley powiedział pół słowem w Warszawie, że może Microsoft ustandaryzuje XAML w Xamarin. Przydałoby się, bo pewną klątwą nad tym językiem jest, że każdy framework ma swoją własną jego odmianę.

#2  Status bar

Nie pokolorujemy go w XAML, ani nawet w cross-platformowym projekcie!  W Android w projekcie na tę platformę pilnujemy ustawiania:

<item name="colorPrimaryDark">#e57373</item>

w Resources/values/styles.xml. W iOS zdaje się dopilnowałem, by w Info.plist było:

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>

#3 Toolbar

Zrobiłem odpowiedni styl do NavigationPage. Musi być do NavigationPage, jak zrobimy do ContentPage nie zadziała!  Widzę kilka mankamentów. Nie uciekając się do natywnych renderingów jestem obowiązywany podawać bitmapowe ikony, a natywnie np. w iOS mogłem podać słowo “search” i to wystarczało. No, ale mam unifikację w XAML. Inna rzecz, to nie udało mi się póki co ostylować koloru popupu dla akcji secondary w przypadku Android. Nawet natywny sposób jaki stosowałem w Xamarin.Android nie chce działać z Xamarin.Forms!!!  O tym, że w XAML nie ma gdzie tego zrobić nawet nie mówię. Jeśli chodzi o Android to kolejne pytanie, co się stało z cieniem toolbara. Xamarin niby wspiera Material Design poprzez FormsAppCompatActivity, ale czemu domyślnie tego cienia nie widać?  Nie mam już siły, uderzę z pytaniami na forum Xamarina.

#4  Nawigacja

Widać fajne nowoczesne podejście z async.  Odpalają się domyślnie jakieś tranzycje między stronami, inne jednak niż w domyślne w moich natywnych rozwiązaniach.

#5  Lokalizacja

Generalnie wykonałem to co na stronie Localizing Xamarin.Forms Apps with RESX Resource Files. Jak w przypadku całego Xamarin.Forms widać, że pewną małą część pozostawia się rozwiązaniom natywnym.

#6  Ikony aplikacji

Podmieniłem generalnie te defaultowe na swoje z wcześniejszych solucji. Bez zaskoczenia, pamiętać tylko że Xamarin.Forms wspiera szerszy zakres wersji systemów niż robiłem to tworząc rozwiązania natywne.

To tyle na dziś. Stay tuned!

Brak komentarzy: