Wsparcie dla różnych urządzeń Android występuje obecnie w całej gamie różnych urządzeń. Urządzenia te różnią się: wielkością ekranu, gęstością pikseli, hardware'em, wspieranym sdk Dodatkowo urządzenia te mogą być posiadać system w różnych wersjach językowych SDK pozwala przystosować aplikację do większości tych wypadków
Wspieranie różnych języków Łańcuchy znaków z UI zawsze powinniśmy trzymać w zewnętrznym pliku Tworząc projekt wykorzystując SDK automatycznie tworzony jest folder res/ w którym znajduje się kilka domyślnych folderów i plików, jak np. res/values/strings.xml. Aby dodać wsparcie dla większej ilości języków najpierw musimy znać ich kody alfa-2: http://pl.wikipedia.org/wiki/iso_3166-1 Stąd wiemy np., że Polska ma PL, Francja: FR
Zakładając, że nasza aplikacja domyślnie ma być po angielsku, ale wspierać polski i francuski nasza struktura folderu res powinna być następująca: res/ values/ strings.xml values-pl/ strings.xml values-fr/ strings.xml
Każdy z tych stringów powinien mieć wartości w odpowiednim języku: Angielski, domyślny: /values/strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="title">my Application</string> <string name="hello_world">hello World!</string> </resources>
Polski: /values-pl/strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="title">moja Aplikacja</string> <string name="hello_world">witaj Świecie!</string> </resources>
Francuski: /values-fr/strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="title">mon Application</string> <string name="hello_world">bonjour le monde!</string> </resources>
Znacznik językowy możemy stosować dla każdego typu zasobów z folderu res możemy np. dostarczyć różne bitmapy w zależności od języka systemu operacyjnego. Dzięki takiemu rozwiązaniu odwołując się do stringa w kodzie nie musimy przejmować się językiem android zrobi to automatycznie za nas.
Z poziomu kodu: Przykłady odwołań do zasobów: String hello = getresources().getstring(r.string.hello_world); TextView textview = new TextView(this); textview.settext(r.string.hello_world);
Lub w XML-u: <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" />
Wspieranie ekranów Android dzieli urządzenia według dwóch cech: rozmiaru ekranu oraz gęstości pikseli (dpi). Android uruchamiając aplikacje na różnych urządzeniach będzie skalował ją tak aby pasowała, ale zawsze powinno się przygotować różne wersje layoutu pod różne urządzenia aby zoptymalizować wrażenia użytkownika.
Ekrany dzielimy na: small, normal, large, xlarge Gęstości na: low (ldpi), medium (mdpi), high(hdpi), extra high (xhdpi) Orientacja 'portrait' i 'landscape' są także traktowane jak osobne layouty (domyślnie layout jest robiony jako portrait, suffiks -land definiuje layout dla landscape. Należy przygotować alternatywne wersje layoutów oraz bitmap i umieścić je w osobnych folderach, podobnie jak miało to miejsce z językami
Tworzenie różnych layoutów Aby stworzyć różne wersje layoutów umieszczamy je w odpowiednim folderze z sufiksem -<screen_size> w nazwie. Na przykład layout dla dużych ekranów powinien być zapisany w res/layout-large, czyli nasza struktura folderów powinna wyglądać następująco: res/ layout/ main.xml /ayout-large/ main.xml
W kodzie odnosimy się do layoutu tak jak robiliśmy to do tej pory: @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); }
Inny przykład: res/ layout/ main.xml layout-land/ main.xml layout-large/ main.xml layout-large-land/ main.xml
Bitmapy Tworząc bitmapy dobrze jest mieć główny plik w wysokiej rozdzielczości albo w wersji wektorowej i następnie dopasowywać go do gęstości ekranu według: xhdpi: 2.0 hdpi: 1.5 mdpi: 1.0 ldpi: 0.75 Czyli bitmapa rozmiaru 200x200 dla xhdpi, powinna mieć rozmiar 150x150 dla hdpi, 100x100 dla mdpi, 75x75 dla ldpi. Następnie pliki te wstawiamy do odpowiednich folderów:
res/ drawable-xhdpi/ image.png drawable-hdpi/ image.png drawable-mdpi/ image.png drawable-ldpi/ image.png Zasoby ldpi można czasami pominąć android automatycznie przeskaluje hdpi do ekranów ldpi.
ldpi mdpi tvdpi hdpi xhdpi xxhdpi Total Small 9.4% 9.4% Normal 0.1% 15.3% 33.5% 22.8% 7.7% 79.4% Large 0.6% 3.5% 1.2% 0.5% 0.6% 6.4% Xlarge 4.4% 0.3% 0.1% 4.8% Total 10.1% 23.2% 1.2% 34.3% 23.5% 7.7%
Przykład aplikacji bez obsługi ekranów/gęstości: Z obsługą:
Różne platformy W AndroidManifest.xml mamy określone obsługiwane przez nasza aplikację wersje Androida. Dla przykładu: <manifest xmlns:android="http://schemas.android.com/apk/res/android"... > <uses-sdk android:minsdkversion="4" android:targetsdkversion="15" />... </manifest>
Zawsze powinniśmy starać się aby nasza aplikacja była stworzona pod najnowszą wersję androida (target), ale przy okazji obsługiwała co najmniej 90% urządzeń z androidem. Version Codename API Distribution 2.2 Froyo 8 2.2% 2.3.3-2.3.7 Gingerbread 10 28.5% 3.2 Honeycomb 13 0.1% 4.0.3-4.0.4 Ice Cream Sandwich 15 20.6% 4.1.x 16 36.5% 4.2.x Jelly Bean 17 10.6% 4.3 18 1.5%
Android umożliwia sprawdzać w wersję api w czasie uruchamiania aplikacji: private void setupactionbar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ActionBar actionbar = getactionbar(); actionbar.setdisplayhomeasupenabled(true); } W plikach XML-owych także można spokojnie używać znaczników z nowszych wersji SDK bez obawy o działanie aplikacji na starszych systemach znaczniki te zostaną zignorowane.
Style/Motywy Android pozwala stosować specjalne style/motywy które umożliwiają utrzymanie wyglądu aplikacji na poziomie zgodnym z aktualną wersją systemu. Na przykład: <activity android:theme="@android:style/theme.dialog"> Powoduje, że aktywność otrzyma motyw domyślnego dialog boxa. <activity android:theme="@android:style/theme.translucent"> Powoduje zastosowanie przeźroczystego tła
<activity android:theme="@style/customtheme"> Umożliwia nałożenie na aktywność własnego motywu zdefiniowanego w /res/values/styles.xml <application android:theme="@style/customtheme"> Nałożenie własnego motywu na całą aplikacje.