Zrozumieć Uniwersalne Aplikacje

O idei Universal Apps pisaliśmy na Tabletowo dużo (i mam na myśli DUŻO), ale do tej pory koncentrowaliśmy się na technicznych szczegółach, takich jak współdzielenie środowiska uruchomieniowego, kodu czy systemowych API.

W tym wpisie chciałbym skoncentrować się na innym aspekcie UWA (Universal Windows Platform), a mianowicie interfejsie użytkownika i nawigacji. Bez zrozumienia idei Microsoftu, dotyczącej projektowania UA, trudno zrozumieć dlaczego rozwiązanie proponowane przez MS ma być tak wyjątkowe i… uniwersalne. Należy pamiętać, że termin „Uniwersalne Aplikacje” był już używany w stosunku do niektórych appek Windowsa 8.1 i Windows Phone 8.1. Do tej pory jednak nie były to aplikacje prawdziwie uniwersalne.

Tworząc UA w Visual Studio dla platformy 8.1, powstawała solucja z trzema projektami – jednym dla Windowsa, drugim dla Windows Phone i trzecim – wspólnym kodem dla obu widoków. Według przedstawicieli Microsftu, pozwalało to na współdzielenie nawet do 80% kodu (wariant bardzo optymistyczny), ale wymagało tworzenia całkowicie odrębnych widoków dla obu platform i korzystanie z różnych API. Wynikiem pracy były również osobne paczki dla sklepów W8.1 i WP8.1. Mało tego, UA można było nazwać pary zupełnie niezależnych aplikacji, które współdzieliły ze sobą jedynie stan aplikacji czy gry w chmurze, a kod miały całkowicie osobny.

Gallo-blog-1-v2

Windows 10 całkowicie zmienia to podejście. Istotą jest tworzenie jednego kodu, korzystanie z jednego API i stworzenie jednej paczki z binarką i plikami pomocniczymi – dla smartfonów, tabletów, laptopów, desktopów, Xboxa, Huba, HoloLens czy urządzeń IoT. W tym momencie nasuwa się pytanie – jak to zrobić, skoro urządzenia te mają całkowicie różne wielkości ekranów i sposoby interakcji z użytkownikiem (dotyk, myszka, głos, pad,itd…)? Z pomocą przychodzą cztery główne elementy: Relative Panel, Effective Pixel, Split View i State Triggers, które wraz z innymi kontrolkami tworzą szeroko pojęty Adaptive UX, czyli interfejs adaptujący się do ekranu i urządzenia użytkownika.

RelativePanel

RelativePanel to kontrolka XAML-a (język/markup do tworzenia interfejsów w Visual Studio) pozwalająca na dowolne ustawianie elementów na ekranie relatywnie w stosunku do siebie, a nie w stosunku do krawędzi bocznych całego ekranu. W połączeniu z dynamicznym rozmieszczaniu elementów wewnątrz paneli, pozwala to na uzyskanie efektu, przypominającego HTML-owy „responsive design”. Stopniowo zwężając okno aplikacji elementy najpierw się zwężają, a potem zmieniają kolejność.

relative-panel1

Najprostszy przykład – mając dwukolumnowy layout „lewo-prawo”, przy zwężeniu szerokości aplikacji poniżej pewnego progu, rozmieszczenie elementów zmieni się na „góra-dół”. Lewa kolumna będzie na przykład na górze, a prawa na dole. Mało tego, poniżej pewnych szerokości możemy na przykład zdecydować, że pewne panele (elementy interfejsu) nie będą się wyświetlać w ogóle. I wszystko to bez konieczności pisania ani jednej linii kodu w C#. Wszystko załatwi markup w XAMLU, bez potrzeby ręcznego obkodowywania triggerów, które uruchamiałyby się wraz ze zmianami szerokości aplikacji/ekranu. Dzięki temu można tworzyć dynamiczne interfejsy, które dostosowują się do szerokości ekranu.

Effective Pixel

Jednak proste skalowanie, zwężanie i zmiana kolejności nie wystarczą. Gdyby to były jedyne mechanizmy, fonty i ikony oraz pozostałe elementy interfejsu, na małych ekranach byłyby zdecydowanie zbyt małe i nieczytelne. Windows 10 i platforma uniwersalnych aplikacji wprowadza jednak pojęcie „efektywnego piksela”, w odróżnieniu od fizycznego piksela, nie ma on wielkości absolutnej, a relatywną i zależy ona między innymi od średniej odległości, z jakiej oglądamy ekran dla danego urządzenia. Używając efektywnych pikseli przy określaniu wielkości elementów interfejsu (fontów, belek, ikon, itd…) znika nam problem zastanawiania się jak dany element będzie prezentował się na całej gamie urządzeń.

effectivePixels

Co to oznacza w praktyce? Projektant określa wielkość elementu w jednostkach px, ale mimo tego, że mają one wartość absolutną (np. 24px), to w praktyce, system operacyjny uwzględnia efekt skalowania i wielkość ekranu w taki sposób, żeby pozorna (postrzegana) wielkość elementu była taka sama bez względu na to, z jakiego urządzenia korzystamy. Oczywiście ten sam element na smartfonie może mieć 8 mm a na telewizorze 4 cm, ale dzięki różnicy wielkości ekranów i różnicy odległości z jakiej je oglądamy – cały interfejs będzie wyglądał podobnie.

Split View

Split View to kontrolka kontenera, który może być wykorzystywany między innymi do tworzenia hamburgerowych menu. Pomijam kwestię zasadności używania hamburgerów do nawigacji, bo to jak zwykle – „zależy od wielu czynników”, jednak udostępnienie natywnej opcji Split View w XAML-u to zdecydowane ułatwienie dla projektantów i programistów, którzy mimo wszystko lubią korzystać z hamburgerowych menu.

spl

Microsoft wzbogacił tę kontrolkę o kilka udogodnień i domyślnych zachowań. W zależności od wielkości ekranu, projektant decyduje czy menu ma być cały czas rozwinięte (duże ekrany) czy schowane (np. w smartfonch). Do tego, możemy korzystać z kilku dodatkowych trybów – wysuwane menu może albo „wypychać” wyświetlaną na ekranie treść albo ją zakrywać – oba z tych zachować w zależności od scenariusza użycia mogą być pożądane.

State Triggers

State Triggers to bardziej mechanizm dla projektantów i programistów, którzy chcieliby żeby ich aplikacje dynamicznie dostosowywały się do wielkości ekranu i urządzenia. Jest on mocno powiązany z kontrolką RelativePanel. Wyzwalacze stanu definiują progową wartość, dla jakiej ma nastąpić zmiana stanu wizualnego (layoutu). Na przykład składnia <AdaptiveTrigger MinWindowWidth=”720″ /> pozwoli na zdefiniowanie akcji, które mają się zdarzyć, w sytuacji gdy ekran będzie niemniejszy niż 720 efektywnych pikseli.

W najprostszych przypadkach, wyzwalane są zależności RelativePanel, a właściwie ich zmiany, na przykład sposób wzajemnego rozmieszczenia: <Setter Target=”best.(RelativePanel.AlignLeftWithPanel)” Value=”true”/>. Triggery te mogą też oczywiście wywoływać bardziej zaawansowane funkcje zapisane w C#.  Przykład użycia takiej składni XAML dla aplikacji sklepu:

code

Jak widać, tak naprawdę tworzone są osobne widoki. Nie są one jednak tworzone dla klas urządzeń, a dla poszczególnych relatywnych wielkości ekranu (effective pixels). Są też w jednym pliku, wygenerowane za pomocą prostej składni XAML-a, bez konieczności angażowania kodu C# i backendowych wyzwalaczy. Docelowo nie tworzą też osobnych paczek do poszczególnych sklepów. Od teraz jest tylko jedno Windows Store i jedna paczka z binakrami i assetami.

USA Today – studium przypadku

Nic jednak nie przemawia do wyobraźni tak mocno jak dobry przykład. Uniwersalna Aplikacja USA Today to moim zdaniem jedna z najlepszych dostępnych UA, a na dodatek znakomicie pokazuje wszystkie wymienione powyżej mechanizmy i kontrolki.

Strona główna – domyślnie hamburgerowe menu rozwinięte – Split View (duży ekran). Elementy (prostokąty) rozciągnięte równomiernie na całą szerokość.

USAToday(10)

Strona główna – po zwinięciu menu (tryb inline), dynamicznie pojawia się nam dodatkowa kolumna.

USAToday(11)

Pojedynczy artykuł – orientacja pozioma – tło

USAToday(12)

Pojedynczy artykuł – orientacja pionowa – tło znika, artykuł na całą szerokość

USAToday(13)

Bardzo mała (smartfonowa) szerokość. Menu automatycznie się chowa (tryb overlay)

USAToday(14)

Widok 50 na 50. Menu domyślnie ukryte. Po rozwinięciu wyświetla się w trybie overlay. Kolumny dwie, na całą szerokość.

USAToday(15)

Rozwinięte menu w trybie overlay

USAToday(18)

Widok pojedynczego artykułu w trybie 50 na 50. Mimo orientacji poziomej – brak tła

USAToday(17)

Czekaliście na podsumowanie? Tym razem go nie będzie. Ten wpis nie ma na celu chwalenia czy ganienia idei Uniwersalnych Aplikacji, a jedynie pokazanie idei i możliwości tego podejścia. A czy deweloperzy za tym pójdą to już zupełnie inna kwestia…