.NET i takie tam

OAC – Orientation Aware Control

leave a comment »

Stworzenie przejrzystego i funkcjonalnego interfejsu dla aplikacji mobilnej nie jest prostym zadaniem. Szczególnie obecnie gdy dynamika rynku urządzeń mobilnych cały czas się zwiększa i co rusz spotykamy się z nowymi rodzajami wyświetlaczy. Projektując interfejs aplikacji mobilnej musimy mieć na uwadze trzy parametry wyświetlania: rozdzielczość, rozmiar ekranu, i tryb wyświetlania. Rozdzielczość określana jest w DPI (ang. dot per inch) im większa tym więcej możemy zmieścić na ekranie. Typowymi rozdzielczościami są QVGA (Quater – VGA) która wynosi 96 DPI i VGA wynosząca 192 DPI. Rozmiar ekranu, podawany jest w pikselach i typowo wynosi 240×320 (szerokość/wysokość). Tryb wyświetlania określa czy nasze okno wyświetlane jest pionowo (vertical/portrait) bądź poziomo (horizontal/landscape).

Rozdzielczością, automatycznie zajmuje się Visual Studio, po za tymi sporadycznymi przypadkami gdy ręcznie tworzymy kontrolki. Musimy wtedy rozmiary komponentu przemnożyć przez, że tak to nazwę, współczynnik skalujący – dostosowujący wymiary do aktualnej rozdzielczości. Skalę możemy określić na przykład tak:


static class Program
{

[MTAThread]
static void Main()
{
  frmScaling f = new frmScaling();

  // rozdzielczość dla której projektowaliśmy aplikację
  const float designResolution = 96.0f;
  System.Drawing.Graphics g = f.CreateGraphics();
  float runningResolution = g.DpiX;

  ScaleFactor = runningResolution / designResoluion;
  g.Dispose();

  Application.Run(f);
}

  // Przemnóż wszystkie 'ręcznie' tworzone kontrolki przez
  // Program.ScaleFactor,
  // Przez większość czasu będą one przyjmowały jedną z
  // trzech wartości:
  // 1 - gdy zaprojektowaliśmy aplikację dla rozdzielczości
  //     na której pracujemy
  // 2 - gdy zaprojektowaliśmy aplikację dla 96dpi ale
  //     pracujemy na 192 dpi
  // 1.365 - gdy zaprojektowaliśmy aplikację dla 96dpi ale
  //     pracujemy na 131dpi (QVGA Smartphone)
  internal static float ScaleFactor;
}

Więcej na ten temat można znaleźć w książce Microsoft Mobile Development Handbook na strony 63 – 66.

Niestety wymiarami ekranów i trybem pracy musimy zająć się sami. Jest kilka sposobów aby ułatwić sobie, życie. Jednym z nich jest projektowanie interfejsu z myślą o kwadratowym ekranie. Mato swoje zalety – interfejs zawsze będzie taki sam niezależnie czy aplikacja pracuje w trybie pionowym czy poziomym. Wadą tego rozwiązania jest to, że na ekranach prostokątnych, marnujemy całkiem sporą ilość wolnej przestrzeni. Myślę, że można wziąć to rozwiązanie pod uwagę dla prostych aplikacji bez wyszukanego interfejsu użytkownika.

Innym rozwiązaniem jest stworzenie osobnych kontrolek – reprezentujących zawartość danego okna – i dynamicznej ich zamianie w zależności od wymaganego położenia. Rozwiązanie to wymaga jednak większego nakładu pracy gdyż nie dość, że musimy zaprojektować dwa różne ekrany i obsłużyć zdarzenie zmiany położenia ekranu. Prosty przykład tego rozwiązania można znaleźć w jednym z wcześniejszych moich postów. Przykład ten prezentuje dodatkowo jak wykorzystać wzorzec MVP (Model-View-Presenter) aby nie duplikować kodu wewnątrz kontrolek.

Kolejnym rozwiązaniem, obecnie chyba najłatwiejszym, jest skorzystanie w Orientation Aware Control w skrócie OAC. OAC jest kontrolką kontenerem i odpowiada funkcjonalności standardowej UserControl. Jednak posiada szereg nowych właściwości dzięki którym, możemy, na tylko jednej (!) kontrolce zaprojektować layout’y dla różnych trybów pracy ekranu. Czyli w sumie cała ciężka praca jest zrobiona za nas – jedyne co nam pozostaje to rozplanować prawidłowe położenie kontrolek.

Komponent OAC możemy pobrać z dwóch źródeł. Pierwszym jest pakiet Microsoft Patterns & Practises – Mobile Client Software Factory (MCSF). Niestety został on wydany prawie dwa lata temu (lipiec 2006) i od tego czasu nie był uaktualniany. Drugim źródłem jest strona www.orientationaware.net – tutaj możemy znaleźć najnowszą wersję tejże kontrolki, niestety jest już to kontrolka komercyjna. Fakt na stronie jest udostępniona wersja Community Edition ale jest ona dość poważnie ograniczona tzn. obsługuje tylko jedną rozdzielczość (QVGA).

Z moich doświadczeń wynika, że wersja kontrolki dostarczona MCSF w zupełności wystarcza i nie powoduje większych problemów. Jednakże trzeba mieć na uwadze, że w przypadku jakichkolwiek kłopotów, możemy mieć problem z otrzymaniem pomocy (ostatnie tematy z forum są datowane na rok 2006), i albo kupimy komercyjną wersję kontrolki, albo sami będziemy musieli zgłębić jej kod źródłowy.

Jak to wszystko działa? Otóż, przede wszystkim musimy dodać referencje do assembly:
Microsoft.Practices.Mobile.UI.OrientationAware.dll
i
Microsoft.WindowsMobile.Status.dll
lub tylko
Clarius.UI.OrientationAware.dll
w przypadku wersji komercyjnej. Kolejnym krokiem będzie utworzenie nowej UserControl i zmianie klasy z której ona dziedziczy na OrientationAwareControl.

 

Teraz możemy otworzyć naszą kontrolkę w designerze, właściwościami na które powinniśmy zwrócić uwagę to Orientation i Resolution. Jak nazwy wskazują Orientation określa jak nasze okno jest położone (vertical/horizontal) a Resolution pozwala nam wybrać rozdzielczość dla jakiej projektujemy nasz interfejs. Kontrolka dostarczona nam przez MS Pattern & Practises pozwala nam na wybór pomiędzy: 240×320 (QVGA), 480×640 (VGA), 240×240 (kwadratowa QVGA), 480×480 (kwadratowa VGA) co w większości przypadków jest wystarczające. Kontrolka dostarczona nam przez Clarius Consulting (www.orientationaware.net) – rozszerza ten zakres i pozwala na definiowanie własnych rozmiarów. Następnie na powierzchni naszej kontrolki umieszczamy resztę elementów, np.:

Gdy jesteśmy zadowoleni z wyglądu kontrolki pora utworzyć interfejs dla trybu landscape. W tym celu możemy zmienić właściwość Orientation z okna Properties bądź skorzystać z menu kontekstowego kontrolki i wybrać ‚Rotate‚. Teraz nie pozostaje nam nic innego jak dostosować wielkość kontrolki i odpowiednio rozmieścić elementy na niej.

Nie jesteśmy bynajmniej ograniczeni tylko do zmiany położenia elementów naszej kontrolki – możemy również zmieniać pozostałe właściwości jak np. ich rozmiary, właściwość Text czy Image. Ograniczeniem z jakim się spotykamy jest niemożliwość dodawania nowych elementów na widokach innych niż domyślny. Jeśli chcemy aby jakaś kontrolka była widoczna tylko w trybie landscape – musimy najpierw przejść do widoku domyślnego domyślnego, tzn. nie tylko położenia horizontal ale także domyślnej rozdzielczości, możemy tego dokonać poprzez wybranie opcji z menu kontekstowego kontrolki ‚Switch to Default Layout‚. Teraz dodajemy nową kontrolkę i ustawiamy jej właściwość Visible na false i zmieniamy ją w kodzie w momencie wykrycia zmiany orientacji ekranu. Właściwości Orientation Aware Control, dla wszystkich trybów wyświetlania, oprócz domyślnego są przechowywane jako zasoby. Dlatego też, jeśli przyjrzymy się pozycji Resources naszej kontrolki zobaczymy coś takiego:

Pojedynczy plik określa właściwości jednego trybu wyświetlania i aby zmniejszyć rozmiar zasobów przechowuje tylko wartości które uległy zmianie z widoku domyślnego.

Problem jaki wiąże się z przechowywaniem właściwości w zewnętrznych zasobach jest to, że są one odczytywane przy każdej zmianie widoku i nie zachowują aktualnego stanu poszczególnych kontrolek. Weźmy na przykład aplikację korzystającą z OAC w którym znajduje się kontrolka TextBox, użytkownik wpisuje do niego dane i zmienia orientację ekranu – w tym momencie właściwości kontrolki OAC są odczytywane z zasobów i zawartość naszej kontrolki zostaje zastąpiona domyślną wartością. Dlatego też musimy sami zadbać o przechowywanie zawartości elementów naszej OAC.

Na koniec kilka szczegółów o których powinniśmy wiedzieć:

  • Forma na której zamierzamy umieścić naszą kontrolkę pochodzącą od OAC powinna mieć ustawioną właściwość AutoScaleMode na None, gdyż skalowanie odbywa się trakcie projektowania i prawidłowe rozmiary są zapisane w zasobach.
  • Gdy projektujemy interfejs dla trybu VGA, wszystkie kontrolki są dwa razy większe niż zazwyczaj. Nie jest to błąd – Visual Studio 2005 (i zapewne VS 2008 też, ale nie testowałem tego) odwzorowuje kontrolki w ich rzeczywistych rozmiarach a ponieważ VGA jest dwa razy lepsza od QVGA na ekranach naszych monitorów otrzymujemy nieco większe niż przywykliśmy. Niestety taka jest specyfika Visual Studio i nie jesteśmy wstanie nic z tym zrobić.

Dodatkowych informacji można szukać na stronach Clarius Consulting bądź w udostępnionym przez Microsoft webcast’cie ‚Designing Zero-Code Adaptive UIs Using the Orientation Aware Control’. Źródła przykładowej aplikacji jest dostępne na tutaj.

Written by sakowicz

Styczeń 30, 2008 @ 9:40 pm

Napisane w .NET CF, Devices

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: