Darmowy fragment publikacji:
Tytuł oryginału: Android in Practice
Tłumaczenie: Tomasz Walczak
Projekt okładki: Studio Gravite / Olsztyn
Obarek, Pokoński, Pazdrijowski, Zaprucki
ISBN: 978-83-246-4810-8
Original edition copyright © 2012 by Manning Publications Co.
All rights reserved.
Polish edition copyright © 2012 by HELION SA.
All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording or by any information storage
retrieval system, without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte
w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za
ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich.
Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne
szkody wynikłe z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie?gimpbi
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis treĂci
WstÚp 11
PodziÚkowania 13
O ksiÈĝce 17
O ilustracji z okïadki 23
CZ}¥m I TO HISTORYCZNE I PODSTAWY ..................................25
1
2
3
Wprowadzenie do Androida 27
1.1. Android w piguïce 30
1.2. HelloAndroid 34
1.3.
Java, ale nie do koñca 45
1.4. Linux, ale nie do koñca 51
1.5. WiÚcej moĝliwoĂci dziÚki bibliotekom natywnym 56
1.6. Potrzebne narzÚdzia 59
1.7. Podsumowanie 67
Podstawy tworzenia aplikacji na Android 69
2.1. Aplikacja DealDroid 70
2.2. Podstawowe cegieïki 72
2.3. Manifest aplikacji 74
2.4. Zasoby 76
2.5. Ukïad, widoki i kontrolki 80
2.6. AktywnoĂci 82
2.7. Adaptery 91
2.8. Intencje i filtry intencji 96
2.9. Obiekty klasy Application 103
2.10. Podsumowanie 105
ZarzÈdzanie cyklem ĝycia i stanem 107
3.1. Czym sÈ aplikacje w Androidzie? 108
3.2. Cykl ĝycia aktywnoĂci 113
3
4
Spis treĂci
3.3. Kontrolowanie stanu egzemplarza aktywnoĂci 125
3.4. Wykonywanie operacji za pomocÈ zadañ 131
3.5. Podsumowanie 133
CZ}¥m II PRAKTYCZNE ROZWIkZANIA .......................................135
4
Precyzja co do piksela 137
4.1. Aplikacja MyMovies 138
4.2. Hierarchie widoków i ich wyĂwietlanie 139
4.3. PorzÈdkowanie widoków w ukïady 143
TECHNIKA 1. Dyrektywy scalania i doïÈczania 152
TECHNIKA 2. ZarzÈdzanie listÈ z pamiÚciÈ stanu 156
TECHNIKA 3. Widoki nagïówka i stopki 161
4.4. RozwiniÚcie informacji o klasach ListView i Adapter 156
0
0
4.5. Stosowanie motywów i stylów 165
0
0
0
4.6. Korzystanie z obiektów graficznych 174
0
TECHNIKA 4. Stosowanie i pisanie stylów 165
TECHNIKA 5. Stosowanie i pisanie motywów 167
TECHNIKA 6. OkreĂlanie stylu tïa widoku ListView 170
TECHNIKA 7. Uĝywanie obiektów graficznych w postaci
ksztaïtów 175
0 TECHNIKA 8. Stosowanie selektorów
obiektów graficznych 179
0 TECHNIKA 9. Skalowanie widoków za pomocÈ
dziewiÚciopolowych obiektów graficznych 182
4.7. Tworzenie przenoĂnych interfejsów uĝytkownika 186
0 TECHNIKA 10. Automatyczne dostosowywanie aplikacji
do róĝnych ekranów 186
0 TECHNIKA 11. Wczytywanie zasobów zaleĝnych
od konfiguracji 191
0 TECHNIKA 12. Uniezaleĝnienie siÚ od pikseli 194
4.8. Podsumowanie 196
Uĝywanie usïug do zarzÈdzania zadaniami
wykonywanymi w tle 199
5.1. WielozadaniowoĂÊ jest najwaĝniejsza 200
5.2. Do czego sïuĝÈ usïugi i jak z nich korzystaÊ? 201
0 TECHNIKA 13. Tworzenie usïugi 202
0 TECHNIKA 14. Automatyczne uruchamianie usïugi 206
5
Spis treĂci
5
0 TECHNIKA 15. Komunikowanie siÚ z usïugÈ 208
0 TECHNIKA 16. Wykorzystanie usïugi do zapisywania
danych w pamiÚci podrÚcznej 214
0 TECHNIKA 17. Tworzenie powiadomieñ 217
5.3. Planowanie i usïugi 222
0 TECHNIKA 18. Uĝywanie klasy AlarmManager 222
0 TECHNIKA 19. Podtrzymywanie dziaïania usïugi 226
0 TECHNIKA 20. Uĝywanie usïugi
Cloud to Device Messaging 229
5.4. Podsumowanie 234
WÈtki i wspóïbieĝnoĂÊ 237
6.1. WspóïbieĝnoĂÊ w Androidzie 238
0 TECHNIKA 21. Proste wÈtki 240
0 TECHNIKA 22. Przekazywanie informacji o zmianach
miÚdzy wÈtkami 243
0 TECHNIKA 23. ZarzÈdzanie wÈtkami w puli wÈtków 249
6.2. Korzystanie z klasy AsyncTask 255
0 TECHNIKA 24. Implementowanie prac za pomocÈ klasy
AsyncTask 256
0 TECHNIKA 25. Przygotowanie do zmian
w konfiguracji 261
6.3. Róĝne techniki 268
0 TECHNIKA 26. WyĂwietlanie ekranów powitalnych
za pomocÈ zegarów 268
0 TECHNIKA 27. Implementowanie niestandardowych
pÚtli komunikatów 272
6.4. Podsumowanie 276
Lokalne zapisywanie danych 279
7.1. Odczyt i zapis plików 280
0 TECHNIKA 28. Korzystanie z pamiÚci wewnÚtrznej 282
0 TECHNIKA 29. Korzystanie z pamiÚci zewnÚtrznej 286
0 TECHNIKA 30. Uĝywanie katalogów
na pamiÚÊ podrÚcznÈ 292
0 TECHNIKA 31. Stosowanie synchronizacji przy zapisie
plików 293
7.2. Przechowywanie ustawieñ 294
0 TECHNIKA 32. Odczyt i zapis ustawieñ 295
6
7
6
Spis treĂci
8
9
0 TECHNIKA 33. Korzystanie z klasy PreferenceActivity 296
7.3. Korzystanie z bazy danych 299
0 TECHNIKA 34. Tworzenie bazy danych
i obiektów modelu 303
0 TECHNIKA 35. Tworzenie obiektów DAO
i menedĝera danych 312
7.4. Badanie baz SQLite 323
7.5. Podsumowanie 325
Wspóïuĝytkowanie danych miÚdzy aplikacjami 327
8.1. Wspóïuĝytkowanie danych miÚdzy procesami 328
0 TECHNIKA 36. Stosowanie intencji 329
0 TECHNIKA 37. Zdalne wywoïania procedur 335
0 TECHNIKA 38. Wspóïuĝytkowanie danych (i innych
elementów) przez wspóïdzielenie kontekstu 341
8.2. DostÚp do niestandardowych danych 347
0 TECHNIKA 39. Korzystanie ze standardowych dostawców
treĂci 347
0 TECHNIKA 40. Korzystanie z niestandardowego
dostawcy treĂci 352
8.3. Podsumowanie 356
Protokóï HTTP i usïugi sieciowe 357
9.1. Podstawy pracy z sieciÈ z wykorzystaniem
protokoïu HTTP 358
0 TECHNIKA 41. Protokóï HTTP
i klasa HttpURLConnection 360
0 TECHNIKA 42. Praca z protokoïem HTTP za pomocÈ klasy
HttpClient Apache’a 366
0 TECHNIKA 43. Konfigurowanie obiektu klasy HttpClient
bezpiecznego ze wzglÚdu na wÈtki 370
9.2. Korzystanie z usïug sieciowych generujÈcych dane
w formatach XML i JSON 375
0 TECHNIKA 44. Przetwarzanie danych w XML-u
za pomocÈ interfejsu SAX 379
0 TECHNIKA 45. Przetwarzanie dokumentów XML
na podstawie specyfikacji XmlPull 385
0 TECHNIKA 46. Przetwarzanie danych
w formacie JSON 389
Spis treĂci
7
10
11
9.3. Elegancka obsïuga awarii sieci 393
0 TECHNIKA 47. Ponawianie ĝÈdañ
za pomocÈ komponentów obsïugi 393
0 TECHNIKA 48. Obsïuga zmian konfiguracji sieci 397
9.4. Podsumowanie 400
Najwaĝniejsza jest lokalizacja 403
10.1. Krótkie wprowadzenie
do wspóïrzÚdnych geograficznych 404
10.2. Menedĝery, dostawcy i odbiorniki poïoĝenia 407
0 TECHNIKA 49. Sprawdzanie stanu dostawcy poïoĝenia 414
0 TECHNIKA 50. OkreĂlanie aktualnego poïoĝenia
za pomocÈ odbiornika LocationListener 416
10.3. Tworzenie aplikacji z wykorzystaniem map 422
0 TECHNIKA 51. Przeksztaïcanie adresu
na wspóïrzÚdne geograficzne 425
0 TECHNIKA 52. Tworzenie aktywnoĂci MapActivity
z powiÈzanym widokiem MapView 427
0 TECHNIKA 53. WyĂwietlanie elementów OverlayItems
w widoku MapView 430
10.4. Podsumowanie 433
Uatrakcyjnianie aplikacji za pomocÈ multimediów 435
11.1. Funkcje zbyt zaawansowane
dla telefonu wielofunkcyjnego 436
0 TECHNIKA 54. Wykrywanie moĝliwoĂci 437
11.2. ZarzÈdzanie multimediami 440
0
0
TECHNIKA 55. Korzystanie z zasobów i plików 440
TECHNIKA 56. Korzystanie z dostawców
treĂci multimedialnych 447
0 TECHNIKA 57. Uĝywanie intencji i aktywnoĂci 450
11.3. Odtwarzanie multimediów 453
0 TECHNIKA 58. ZdjÚcia i proste animacje 454
0 TECHNIKA 59. Kontrolowanie děwiÚku 458
0 TECHNIKA 60. WyĂwietlanie filmów 462
11.4. Rejestrowanie multimediów 465
0 TECHNIKA 61. Robienie zdjÚÊ 465
0 TECHNIKA 62. Rejestrowanie děwiÚku i filmów 470
11.5. Podsumowanie 475
8
12
Spis treĂci
Grafika dwu- i trójwymiarowa 477
12.1. Rysowanie z wykorzystaniem bibliotek
do obsïugi grafiki dwuwymiarowej 478
0 TECHNIKA 63. Przechodzenie
do trybu peïnoekranowego 480
0 TECHNIKA 64. Rysowanie prostych ksztaïtów 481
0 TECHNIKA 65. CiÈgïe wyĂwietlanie widoku
w wÈtku interfejsu uĝytkownika 484
0 TECHNIKA 66. WyĂwietlanie tekstu na ekranie 485
0 TECHNIKA 67. OkreĂlanie czcionki
przy wyĂwietlaniu tekstu 487
0 TECHNIKA 68. WyĂwietlanie bitmap 489
0 TECHNIKA 69. Stosowanie efektów dwuwymiarowych 490
12.2. Grafika trójwymiarowa i biblioteka OpenGL ES 493
0 TECHNIKA 70. Rysowanie pierwszego trójkÈta 500
0 TECHNIKA 71. Tworzenie piramidy 504
0 TECHNIKA 72. Kolorowanie piramidy 510
0 TECHNIKA 73. Dodawanie tekstury do piramid 513
12.3. Podsumowanie 519
CZ}¥m III POZA STANDARDOWE ROZWIkZANIA .........................521
13
Testowanie i instrumentacja 523
13.1 Testowanie aplikacji na Android 525
0 TECHNIKA 74. Prosty test jednostkowy aplikacji
na Android 533
13.2. PociÈganie za sznurki — instrumentacja w Androidzie 538
0 TECHNIKA 75. Testy jednostkowe aktywnoĂci 539
0 TECHNIKA 76. Scenariusz uĝytkownika jako testy
funkcjonalne 544
0 TECHNIKA 77. Eleganckie testy z wykorzystaniem
frameworku Robotium 549
13.3. Poza instrumentacjÚ — atrapy i testy losowe 554
0 TECHNIKA 78. Atrapy i sposoby ich stosowania 554
0 TECHNIKA 79. Przyspieszanie testów jednostkowych
z zastosowaniem Robolectrica 561
0 TECHNIKA 80. Przeprowadzanie testów obciÈĝeniowych
za pomocÈ narzÚdzia Monkey 567
13.4. Podsumowanie 573
Spis treĂci
9
14
15
ZarzÈdzanie budowaniem 575
14.1. Budowanie aplikacji na Android 577
0 TECHNIKA 81. Budowanie aplikacji za pomocÈ Anta 583
14.2. ZarzÈdzanie procesem budowania za pomocÈ Mavena 592
0 TECHNIKA 82. Budowanie za pomocÈ Mavena 595
0 TECHNIKA 83. Wtyczka Mavena
dla Ărodowiska Eclipse 607
0 TECHNIKA 84. NarzÚdzie
maven-android-sdk-deployer 610
14.3. Serwery budowania i ciÈgïe budowanie 615
0 TECHNIKA 85. CiÈgïe budowanie z wykorzystaniem
Hudsona 617
0 TECHNIKA 86. Budowanie macierzowe 625
14.4. Podsumowanie 630
Pisanie aplikacji na tablety z Androidem 633
15.1. Przygotowania do tworzenia aplikacji na tablety 635
0 TECHNIKA 87. Wykorzystywanie istniejÈcego kodu
za pomocÈ projektów bibliotek 635
0 TECHNIKA 88. Tworzenie aplikacji przeznaczonej
na tablety 638
15.2. Podstawowe informacje o tabletach 641
0 TECHNIKA 89. Fragmenty 642
0 TECHNIKA 90. Pasek akcji 650
0 TECHNIKA 91. PrzeciÈganie 655
15.3. Podsumowanie 662
Dodatek A
Dodatek B
NarzÚdzia do debugowania 665
Niestandardowe techniki tworzenia aplikacji
na Android 677
ProGuard 687
Dodatek C
Dodatek D Monkeyrunner 701
Skorowidz 713
10
Spis treĂci
Pisanie aplikacji na tablety
z Androidem
W tym rozdziale
Q Stosowanie fragmentów
Q Pasek akcji
Q Implementowanie przeciągania
Wszystko staje siÚ coraz wiÚksze. Dlatego obecnie naleĝy pisaÊ programy
w bardziej wyrafinowany sposób.
Bill Budge
Byï rok 2001. Microsoft, najwiÚksza firma technologiczna na Ăwiecie, zaprezen-
towaï przeïomowÈ wersjÚ niezwykle popularnego systemu operacyjnego —
Windows XP Tablet PC Edition. Zdaniem Microsoftu miaï to byÊ poczÈtek ery
urzÈdzeñ dotykowych. Wiemy, jak to siÚ skoñczyïo. System XP Tablet PC Edition
okazaï siÚ niewypaïem.
Tak naprawdÚ komputery z systemem XP Tablet nie byïy pierwszymi urzÈ-
dzeniami z wyĂwietlaczem dotykowym przeznaczonymi na rynek masowy. Dzie-
siÚÊ lat wczeĂniej inĝynierowie z Apple’a opracowali prototyp, który w przeksztaï-
conej postaci wprowadzono na rynek jako komputer Newton. Opracowane 10 lat
póěniej przez Microsoft komputery Tablet PC byïy podejrzanie podobne do
Newtona. Jednak prototypowa wersja Newtona nigdy nie trafiïa do sprzedaĝy;
komputery z tej rodziny staïy siÚ za to poprzednikami palmtopów.
Stwierdzenie, ĝe urzÈdzenia dotykowe przez wiele lat byïy ogïaszane jako
nastÚpny wielki hit, to powaĝne niedomówienie. Moĝna uznaÊ, ĝe wczeĂniejsze
633
634
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
próby zakoñczyïy siÚ niepowodzeniem, poniewaĝ producenci próbowali prze-
ksztaïciÊ komputery PC w tablety. DwadzieĂcia lat po opracowaniu prototypo-
wego tabletu Newton staïo siÚ oczywiste, ĝe naturalnym urzÈdzeniem dotykowym
sÈ smartfony i to na nich naleĝy wzorowaÊ tablety. W ten sposób powstaïy iPad
Apple’a i Android dla tabletów. W wersji Android 3.0 (Honeycomb) wprowadzono
istotne zmiany, opracowane z myĂlÈ o tabletach. Co to oznacza dla programistów
aplikacji na Android?
JeĂli juĝ udostÚpniasz w sklepie Android Market kilka aplikacji, byÊ moĝe
nasuwa Ci siÚ pytanie: „Co powinienem zrobiÊ, aby programy dziaïaïy na table-
tach?”. Liczba uĝytkowników tabletów jest znacznie mniejsza niĝ liczba osób
korzystajÈcych z telefonów. Zyskanie popularnoĂci przez nowe urzÈdzenia, jakimi
sÈ tablety, wymaga czasu, a uĝytkowników smartfonów sÈ miliony. Prawdopodob-
nie duĝo wiÚksze zyski przyniesie inwestowanie w rozwijanie aplikacji na Android
przeznaczonych na smartfony, a nie na tablety. Jest to prawdÈ zwïaszcza w przy-
padku nowych aplikacji. TworzÈc programy na smartfony, dotrzesz do znacznie
wiÚkszej grupy odbiorców.
IstniejÈ jednak wyjÈtki od tej reguïy. Niektóre rodzaje aplikacji lepiej nadajÈ
siÚ dla tabletów niĝ dla smartfonów. Na przykïad czytniki wiadomoĂci, aplikacje
z sieci spoïecznoĂciowych, sklepy internetowe czy inne programy wyĂwietlajÈce
bogate materiaïy wyglÈdajÈ znacznie lepiej na wiÚkszym ekranie. Na smartfonie
powiÈzane informacje trzeba wyĂwietlaÊ na dwóch lub trzech ekranach, a na
tablecie moĝna je zaprezentowaÊ na jednej angaĝujÈcej czytelnika stronie. Nawet
w innych obszarach wczesne wprowadzanie aplikacji na tablety do sklepu Android
Market przynosi powaĝne korzyĂci. Program moĝe zyskaÊ popularnoĂÊ z uwagi
na niewielkÈ konkurencjÚ, co zapewnia dobrÈ pozycjÚ wyjĂciowÈ, kiedy wiÚcej
osób zacznie kupowaÊ tablety i szukaÊ ciekawych aplikacji w sklepie.
Niezaleĝnie od tego, czy lubisz nowinki, czy nie, w pewnym momencie
zechcesz utworzyÊ aplikacjÚ na tablety (w przeciwnym razie prawdopodobnie nie
czytaïbyĂ tego rozdziaïu). W tym rozdziale wzbogacamy aplikacjÚ DealDroid
z rozdziaïu 2. i tworzymy jej wersjÚ na tablety. Gotowy produkt przedstawiono
na rysunku 15.1.
Decyzji o utworzeniu aplikacji na tablety nie podejmuje siÚ stopniowo. Trzeba
od poczÈtku stwierdziÊ, ĝe program ma dziaïaÊ w tabletach. Rozwijanie takich
aplikacji jest ekscytujÈce, poniewaĝ tablety w porównaniu ze smartfonami otwie-
rajÈ przed programistami wiele nowych moĝliwoĂci. Liczne typowe problemy,
na przykïad maïy ekran, niewielka iloĂÊ pamiÚci, koniecznoĂÊ obsïugi dawnych
wersji Androida i wolna sieÊ, w tabletach sÈ mniej dotkliwe. Jednak zanim
zaczniemy tworzyÊ fragmenty peïne widoków StackView, warto zastanowiÊ siÚ,
jakie elementy aplikacji sÈ juĝ gotowe i jak je wykorzystaÊ.
15.1.
Przygotowania do tworzenia aplikacji na tablety
635
15.1. Przygotowania do tworzenia aplikacji na tablety
Rysunek 15.1.
Aplikacja DealDroid
w wersji na tablety
0
Pisanie programów na tablety nie polega tylko na stosowaniu nowych interfejsów
API i wiÚkszych grafik. Musisz zdecydowaÊ, czy chcesz utworzyÊ odrÚbnÈ aplikacjÚ,
czy rozwinÈÊ istniejÈcy program na smartfony, tak aby dziaïaï poprawnie takĝe
na tabletach. W tym rozdziale koncentrujemy siÚ na pisaniu nowych aplikacji.
Pozwala to wykorzystaÊ wszystkie moĝliwoĂci Androida 3.0. Wszystkie (lub pra-
wie wszystkie) techniki z tego rozdziaïu moĝna zastosowaÊ w czasie tworzenia
standardowych aplikacji.
TECHNIKA 87. Wykorzystywanie istniejącego kodu za pomocą
projektów bibliotek
ChoÊ tworzymy odrÚbnÈ aplikacjÚ przeznaczonÈ na tablety z Androidem, nie
oznacza to, ĝe program jest zupeïnie odmienny od rozwiÈzañ tworzonych na
smartfony. Obie wersje aplikacji majÈ wiele wspólnych funkcji i mogÈ korzystaÊ
nawet z tych samych danych. Dane te moĝna przechowywaÊ lokalnie w urzÈdzeniu
lub w chmurze na serwerze. Sposób dostÚpu do takich danych, a nawet porzÈd-
kowania ich po pobraniu do pamiÚci lokalnej jest taki sam jak w smartfonach.
Na szczÚĂcie istnieje dobry sposób na wspóïuĝytkowanie kodu przez róĝne apli-
kacje na Android.
PROBLEM
W nowej aplikacji na tablety zamierzamy wykorzystaÊ kod istniejÈcego programu
na smartfony. Chcemy, aby istniaïa tylko jedna kopia kodu. Pozwala to dodawaÊ
nowe funkcje, naprawiaÊ bïÚdy i wykonywaÊ podobne zadania w jednym miejscu.
ROZWIĄZANIE
Sposobem na wspóïuĝytkowanie kodu miÚdzy aplikacjami na Android jest zasto-
sowanie projektów bibliotek dla Androida. Takie projekty dobrze nadajÈ siÚ do
porzÈdkowania kodu i wprowadzono je w tym samym czasie co Android 2.2.
Projekty bibliotek nie sÈ przeznaczone tylko dla tabletów i Androida 3.0 —
636
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
pozwalajÈ wspóïuĝytkowaÊ kod takĝe miÚdzy róĝnymi aplikacjami na smartfony.
Taki projekt jest bardzo przydatny przy tworzeniu aplikacji, która ma dziaïaÊ na
smartfonach i tabletach.
WspomnieliĂmy juĝ, ĝe projekty bibliotek wprowadzono w tym samym okre-
sie co Android 2.2. Dostosowano je jednak do jeszcze wczeĂniejszych wersji
Androida. Moĝliwe, ĝe przechowujesz kod w takich bibliotekach i moĝesz
natychmiast wykorzystaÊ je do tworzenia aplikacji na tablety na podstawie istnie-
jÈcego kodu programów na smartfony. JeĂli tak jest, moĝesz przejĂÊ bezpoĂrednio
do nastÚpnej techniki. Jeĝeli jednak jeszcze nie stosujesz projektów bibliotek,
czeka CiÚ refaktoryzacja i zmiana uporzÈdkowania kodu.
W tej technice przeksztaïcamy aplikacjÚ DealDroid przedstawionÈ po raz
pierwszy w rozdziale 2. na program na tablety. Caïy kod aplikacji DealDroid
znajduje siÚ w jednym projekcie aplikacji na Android. Musimy to zmieniÊ. Na
rysunku 15.2 pokazano nowy sposób uporzÈdkowania kodu, pozwalajÈcy wyko-
rzystaÊ ten kod w nowym projekcie aplikacji na tablety.
Na rysunku 15.2 widoczne sÈ projekty DealsLib i TabletDeals. DealsLib to
projekt biblioteki dla Androida, obejmujÈcy kod wspóïuĝytkowany przez aplikacje
na smartfony i tablety. TabletDeals to projekt aplikacji na tablety. W tym roz-
dziale opisujemy go bardzo szczegóïowo. Na rysunku widaÊ, jaki kod znajduje
siÚ w projekcie biblioteki. Umieszczono w niej (w pakiecie com.manning.aip.
´dealdroid.xml) caïy kod do pobierania danych z internetu i ich przetwarzania.
Kod ten moĝe byÊ taki sam dla tabletów i smartfonów. Dane w formacie XML
sÈ przetwarzane na obiekty modelu (okreĂlone w pakiecie com.manning.aip.
´dealdroid.model) uĝywane przez aplikacjÚ. Takĝe kod tych obiektów jest czÚ-
ĂciÈ biblioteki.
W pakiecie najwyĝszego poziomu (com.manning.aip.dealdroid) znajduje siÚ
kilka innych klas. NajciekawszÈ z nich jest DealsApp. Jest to klasa typu Application
uĝywana w obu aplikacjach. Obejmuje pamiÚÊ podrÚcznÈ z danymi, a takĝe stan
aplikacji. Stan w aplikacjach na tablety mógïby byÊ inny, jednak tu jest taki sam,
dlatego wspomnianÈ klasÚ moĝna wspóïuĝytkowaÊ w wersjach programu na
smartfony i tablety.
Ponadto miÚdzy aplikacjami wspóïuĝytkowane sÈ niektóre zasoby, przede
wszystkim pliki strings.xml i plurals.xml. WspóïuĝytkowaÊ moĝna takĝe inne
zasoby, na przykïad obiekty graficzne.
OMÓWIENIE
Projekty bibliotek dajÈ duĝe moĝliwoĂci. ProgramiĂci — zwïaszcza piszÈcy pakiety
aplikacji wspóïuĝytkujÈcych duĝe fragmenty kodu — dobitnie domagali siÚ tego
mechanizmu. CzÚsto wspólny kod sïuĝy do obsïugi dostÚpu do sieci i modelu
danych, podobnie jak w przykïadzie. Nieraz wspólny jest teĝ kod do uwierzy-
telniania uĝytkowników i póěniejszego zarzÈdzania informacjami o toĝsamoĂci
(na przykïad znacznikami uwierzytelniajÈcymi i (lub) okreĂlajÈcymi uprawnienia).
0
TECHNIKA 87. Wykorzystywanie istniejÈcego kodu za pomocÈ projektów bibliotek
637
Rysunek 15.2. Kod przygotowany
do wspóáuĪytkowania z aplikacją
na tablety
Tego rodzaju kod czÚsto obejmuje elementy interfejsu uĝytkownika, poniewaĝ
programiĂci zwykle starajÈ siÚ ujednoliciÊ sposób logowania siÚ do aplikacji.
Uzyskanie tego efektu nie jest trudne, gdyĝ w bibliotece moĝna umieĂciÊ aktyw-
noĂci, XML-owy kod ukïadu itd. Dla projektu biblioteki trzeba teĝ utworzyÊ plik
638
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
AndroidManifest.xml. Moĝna w nim deklarowaÊ aktywnoĂci, usïugi i inne ele-
menty — tak jak w innych manifestach. JeĂli jednak chcesz wykorzystaÊ w apli-
kacji aktywnoĂÊ z projektu biblioteki (lub inny komponent deklarowany w mani-
feĂcie), musisz zadeklarowaÊ tÚ aktywnoĂÊ w pliku AndroidManifest.xml aplikacji.
Manifest projektu biblioteki peïni funkcjÚ menu dostÚpnych komponentów,
które trzeba zadeklarowaÊ w pliku manifestu aplikacji.
Kod moĝna wspóïuĝytkowaÊ miÚdzy projektami na róĝne sposoby. JeĂli korzy-
stasz ze Ărodowiska Eclipse (albo Anta, Mavena lub innego narzÚdzia zarzÈdzajÈ-
cego zaleĝnoĂciami), moĝesz utworzyÊ wïasnÈ bibliotekÚ z kolekcjÈ kodu w Javie
i wykorzystaÊ jÈ w aplikacji. ZaleĝnoĂÊ miÚdzy bibliotekÈ a aplikacjÈ moĝe wystÚ-
powaÊ na poziomie kodu ěródïowego lub na poziomie binarnym. W tym drugim
przypadku najpierw naleĝy skompilowaÊ projekt biblioteki bÈdě nawet spakowaÊ
go do archiwum JAR. Utrudnieniem jest wtedy tylko koniecznoĂÊ upewnienia siÚ,
ĝe w kodzie biblioteki nie wystÚpujÈ ĝadne standardowe klasy Javy niedozwo-
lone w Androidzie, a takĝe uĝycie odpowiedniego archiwum android.jar. Przy
stosowaniu projektów bibliotek dla Androida zadania te sÈ wykonywane auto-
matycznie.
InnÈ waĝnÈ zaletÈ projektów bibliotek dla Androida w porównaniu ze stan-
dardowymi bibliotekami Javy jest obsïuga zarzÈdzania zasobami. W przykïadzie
w bibliotece umieszczamy standardowy plik strings.xml. Pozwala to wspóïuĝyt-
kowaÊ ten plik w wersjach na smartfony i tablety. Moĝna teĝ zastÈpiÊ konkretny
ïañcuch znaków lub dodaÊ nowe fragmenty tekstu przez umieszczenie odrÚbnego
pliku strings.xml w projekcie aplikacji. Kompilator scala wtedy zasoby. Dotyczy
to takĝe innych zasobów, na przykïad stylów i obiektów graficznych, a nawet
plików ukïadu.
Teraz, kiedy znasz juĝ dobry sposób na porzÈdkowanie kodu i wspóïuĝytko-
wanie go w aplikacjach na smartfony i tablety, moĝna dokïadniej zastanowiÊ siÚ nad
wersjÈ na tablety. WspomnieliĂmy juĝ, ĝe tworzymy aplikacjÚ przeznaczonÈ
tylko na tablety. Nie zamierzamy rozwijaÊ wersji dziaïajÈcej równie dobrze na
smartfonach i tabletach. Na szczÚĂcie stosowanie naszego podejĂcia jest proste
i przynosi duĝe korzyĂci.
TECHNIKA 88. Tworzenie aplikacji przeznaczonej na tablety
ProgramiĂci aplikacji na Android niechÚtnie mówili o zróĝnicowaniu urzÈdzeñ
(ang. fragmentation). OkreĂlenie to czÚsto stosowali przeciwnicy Androida, twier-
dzÈcy, ĝe zbyt trudno jest tworzyÊ aplikacje na tÚ platformÚ, poniewaĝ trzeba
zapewniÊ obsïugÚ urzÈdzeñ z ekranami o róĝnej wielkoĂci i z innymi niejedno-
litymi cechami. JednoczeĂnie jest to jednak ukryta wartoĂÊ Androida. WïaĂciwy
sposób programowania wymagaï, aby nie robiÊ zaïoĝeñ co do wielkoĂci i pro-
porcji ekranu. ProgramiĂci mieli wiele narzÚdzi do projektowania aplikacji
z ukïadem dostosowujÈcym siÚ do wyĂwietlacza. Kiedy wiÚc pojawiaïy siÚ nowe
urzÈdzenia z ekranami o przekÈtnej wynoszÈcej 4 lub 4,3 cala albo z mniejszymi,
0
0
TECHNIKA 88. Tworzenie aplikacji przeznaczonej na tablety
639
2,5-calowymi wyĂwietlaczami, wiÚkszoĂÊ programów dziaïaïa w nich prawidïowo.
Nawet na pierwszych tabletach z 7-calowymi ekranami i Androidem 2.2 wiÚkszoĂÊ
aplikacji funkcjonowaïa bez problemów (choÊ byïy teĝ wyjÈtki od tej reguïy —
niektórzy programiĂci nie stosowali najlepszych praktyk i w czasie projektowania
ukïadów robili zaïoĝenia dotyczÈce wielkoĂci wyĂwietlacza). Byïo to wielkÈ zaletÈ
maïych tabletów. Kiedy pojawiïy siÚ na rynku, od razu istniaïo wiele aplikacji, które
prawidïowo na nich dziaïaïy.
Jednak w czasie prac nad wiÚkszymi tabletami okazaïo siÚ, ĝe opracowanie
systemu operacyjnego pod kÈtem takich urzÈdzeñ ma duĝe zalety. Dlatego powstaï
Android 3.0. Platforma ta obejmuje elementy sprawiajÈce, ĝe aplikacje mogÈ
dziaïaÊ równie dobrze zarówno na smartfonach, jak i na tabletach. Ponadto pozwala
tworzyÊ atrakcyjne programy przeznaczone tylko na tablety. Wymaga to jednak
zablokowania dostÚpu do aplikacji uĝytkownikom mniejszych urzÈdzeñ.
PROBLEM
Piszemy aplikacjÚ przeznaczonÈ tylko na tablety. Chcemy wykorzystaÊ duĝy
ekran i wszystkie moĝliwoĂci platformy dostÚpne w tabletach. Nie zamierzamy
dostosowywaÊ aplikacji do urzÈdzeñ z mniejszymi ekranami, niezaleĝnie od
wersji Androida dziaïajÈcej na tych urzÈdzeniach.
ROZWIĄZANIE
Moĝliwe, ĝe juĝ znasz rozwiÈzanie. W pliku AndroidManifest.xml naleĝy okreĂliÊ
wszystkie wymagania aplikacji. NastÚpnie filtry w sklepie Android Market spra-
wiÈ, ĝe aplikacja nie bÚdzie pojawiaÊ siÚ w urzÈdzeniach innych niĝ tablety. Na
listingu 15.1 znajduje siÚ fragment manifestu pozwalajÈcy uzyskaÊ ten efekt.
Listing 15.1. W manifeĞcie moĪna okreĞliü, Īe aplikacja jest przeznaczona
tylko na tablety
?xml version= 1.0 encoding= utf-8 ?
manifest xmlns:android= http://schemas.android.com/apk/res/android
package= com.manning.aip.tabdroid
android:versionCode= 1
android:versionName= 1.0
uses-sdk android:minSdkVersion= 11 /
supports-screens android:smallScreens= false
android:normalScreens= false
android:largeScreens= false
android:xlargeScreens= true /
/manifest
Aby aplikacja byïa przeznaczona tylko na tablety, w manifeĂcie trzeba podaÊ dwa
podstawowe wymagania. Otóĝ w urzÈdzeniu musi dziaïaÊ Android 3.0 (Honey-
. Moĝe siÚ wydawaÊ, ĝe to wystarczy.
comb) lub nowsza wersja tej platformy
W koñcu jeĂli dostÚpny jest interfejs API w wersji 11 (Android 3.0) lub nowszej,
moĝna korzystaÊ ze wszystkich interfejsów API potrzebnych w rozwijanej aplikacji.
Gdy powstawaïa ta ksiÈĝka, wersja Android 3.0 byïa najnowsza i dziaïaïa tylko na
tabletach, ale do czasu trafienia tej pozycji na póïki pojawiÈ siÚ prawdopodobnie
640
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
nowsze wersje, które bÚdÈ obejmowaÊ wszystkie funkcje Androida 3.0 i pracowaÊ
zarówno na smartfonach, jak i na tabletach. Dlatego trzeba teĝ okreĂliÊ, ĝe apli-
kacja dziaïa tylko na urzÈdzeniach z ekranami xlarge
. Ten rozmiar wyĂwie-
tlaczy wprowadzono w Androidzie 2.3. Odpowiada on ekranom majÈcym przy-
najmniej siedem cali. Po okreĂleniu w manifeĂcie tych dwóch wymagañ moĝna
mieÊ pewnoĂÊ, ĝe kaĝde urzÈdzenie, na którym uruchamiana jest aplikacja, to
tablet ze zoptymalizowanymi pod jego kÈtem interfejsami API wprowadzonymi
w wersji Honeycomb.
Naleĝy wspomnieÊ o jeszcze jednym aspekcie programowania aplikacji na
tablety. W czasie pisania aplikacji na smartfony programiĂci czÚsto zakïadajÈ, ĝe
urzÈdzenie zwykle znajduje siÚ w orientacji pionowej. Na szczÚĂcie system ope-
racyjny dobrze obsïuguje zmiany orientacji, dlatego nawet jeĂli programista caï-
kowicie zapomni o przygotowaniu wersji dla poziomego ukïadu ekranu, aplikacja
prawdopodobnie bÚdzie dziaïaÊ poprawnie po obróceniu urzÈdzenia. Warto
jednak zastanowiÊ siÚ nad trybem poziomym, a czasem dobrze jest nawet przy-
gotowaÊ dla niego odrÚbne ukïady. W Androidzie standardowo naleĝy utworzyÊ
katalog ze zoptymalizowanymi plikami XML z kodem ukïadów. Inna moĝliwoĂÊ
to pominiÚcie orientacji poziomej i obsïugiwanie tylko trybu pionowego. Ma to
pewne zalety, choÊ uĝytkownicy urzÈdzeñ z wysuwanymi klawiaturami nie bÚdÈ
zadowoleni z aplikacji napisanej w ten sposób.
Tablety róĝniÈ siÚ od smartfonów. Orientacja to jeden z obszarów, gdzie
róĝnice miÚdzy tymi typami urzÈdzeñ sÈ duĝe. Z tabletów zwykle korzysta siÚ
w orientacji poziomej. Dlatego standardowo pliki ukïadu dla tej orientacji
umieszcza siÚ w katalogu /res/layout, a pliki dla trybu pionowego — w katalogu
/res/layout-port. JeĂli korzystasz z wtyczki ADT dla Ărodowiska Eclipse, mecha-
nizm tworzenia interfejsu uĝytkownika z tej wtyczki pomoĝe Ci w rozwijaniu
aplikacji na tablety, co pokazano na rysunku 15.3.
OMÓWIENIE
Opisane tu podejĂcie pod wieloma wzglÚdami róĝni siÚ od tworzenia typowych
aplikacji na Android. Zwykle warto obsïugiwaÊ jak najwiÚcej róĝnych wyĂwie-
tlaczy. Tu wykluczamy wszystkie wymiary oprócz jednego. Kiedy pojawiïy siÚ
pierwsze tablety z wersjÈ Honeycomb Androida, nie tylko miaïy podobne wymiary,
ale teĝ tÚ samÈ rozdzielczoĂÊ ekranu. Byïo to coĂ nowego dla programistów apli-
kacji na Android, przyzwyczajonych do tworzenia rozwiÈzañ z uwzglÚdnieniem
ekranów o róĝnej wielkoĂci i rozdzielczoĂci. Od czasów urzÈdzeñ G1 nie moĝna
byïo tworzyÊ programów dostosowanych do ekranu o konkretnych cechach (przy
czym fizyczne wymiary poszczególnych modeli tabletów byïy zróĝnicowane).
Unikaj jednak stosowania przestarzaïych ukïadów AbsoluteLayout lub podawania
wymiarów w ukïadzie za pomocÈ fizycznych pikseli.
PrzedstawiliĂmy projekty bibliotek, najnowsze interfejsy API i ukïady dla
duĝych ekranów. Pora rozpoczÈÊ tworzenie programów na tablety z Androidem.
15.2.
Podstawowe informacje o tabletach
641
15.2.
Rysunek 15.3. Tworzenie interfejsu na tablety z wykorzystaniem wtyczki ADT
Zaczynamy od podstawowych technik, które powinien znaÊ kaĝdy programista
aplikacji na tablety. Ponadto pokazujemy, ĝe techniki te nie sÈ ograniczone do
tabletów i ĝe moĝna je ïatwo wykorzystaÊ takĝe przy tworzeniu aplikacji na
smartfony.
Podstawowe informacje o tabletach
Tablety z Androidem istniaïy juĝ na dïugo przed pojawieniem siÚ Androida 3.0.
Miaïy ekrany o przekÈtnej od piÚciu do siedmiu cali, byïy wiÚc mniejsze niĝ
pierwsze urzÈdzenia z wersjÈ Honeycomb. Takie miniaturowe tablety byïy cie-
kawe same w sobie. Jak juĝ wspomnieliĂmy, wiÚkszoĂÊ aplikacji na Android dzia-
ïaïa w nich prawidïowo. Z uwagi na dodatkowÈ przestrzeñ niektóre takie pro-
gramy wyglÈdaïy caïkiem dobrze. Mimo to moĝna byïo je opisaÊ najwyĝej jako
poprawne. Jest to dowód na to, ĝe Android potrafi dostosowaÊ aplikacjÚ do wyĂwie-
tlacza bez nadmiernego utrudniania pracy uĝytkownikom.
Android 3.0 zaprojektowano tak, aby byï wiÚcej niĝ poprawny. PodejĂcie nie
polegaïo na dostosowaniu Androida do poprawnej pracy na wiÚkszym ekranie
lub na dodaniu nowych komponentów interfejsu uĝytkownika. Twórcy platformy
wprowadzili powaĝne zmiany, aby pomóc programistom w skutecznym pisaniu
aplikacji na urzÈdzenia z wiÚkszymi wyĂwietlaczami. Omawianie podstawowych
technik tworzenia aplikacji na tablety zaczynamy od przyjrzenia siÚ jednemu
z najwaĝniejszych mechanizmów wprowadzonych w wersji Honeycomb. SÈ nim
fragmenty.
642
0
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
TECHNIKA 89. Fragmenty
WspomnieliĂmy juĝ, ĝe Android 3.0 zaprojektowano z myĂlÈ o tabletach. Opra-
cowanie nowej wersji nie polegaïo na dodaniu nowych elementów do wczeĂniej-
szych odmian Androida. Jednym z najlepszych dowodów na to jest interfejs
API fragmentów. Fragmenty umoĝliwiajÈ porzÈdkowanie kodu aplikacji w nowy
sposób, znacznie uïatwiajÈcy radzenie sobie z tworzeniem ukïadów dostosowanych
do duĝych ekranów tabletów z Androidem. Jednak mechanizm ten jest przydatny
nie tylko w programach na tablety.
PROBLEM
Chcemy podzieliÊ kod aplikacji na moduïy, aby moĝna byïo stosowaÊ zupeïnie
odmienne ukïady dla orientacji poziomej i pionowej bez koniecznoĂci powielania
kodu oraz funkcji.
ROZWIĄZANIE
RozwiÈzanie polega na uĝyciu fragmentów do uporzÈdkowania kodu. Stosowanie
róĝnych ukïadów dla orientacji poziomej i pionowej nie jest niczym nowym.
W przypadku tabletów istotna jest natomiast iloĂÊ miejsca na ekranie. W smart-
fonach, gdzie wyĂwietlacze sÈ mniejsze, w ukïadach poziomych i pionowych
zwykle dostÚpne sÈ te same informacje oraz funkcje. Zmiana orientacji prowadzi
do sensownego nowego uporzÈdkowania elementów. W tabletach nie jest niczym
niezwykïym wyĂwietlanie na ekranie odmiennych komponentów w róĝnych
ukïadach. Przyjrzyjmy siÚ konkretnemu przykïadowi.
Aplikacja DealDroid (rozdziaï 2.) umoĝliwia uĝytkownikom wyĂwietlanie ofert
dnia z eBaya. Jedna z aktywnoĂci aplikacji wyĂwietla listÚ ofert, a druga — szcze-
góïowe informacje o wybranych ofertach. Na tablecie oba zadania moĝna wyko-
nywaÊ w jednej aktywnoĂci, ale tylko w ukïadzie poziomym. Na rysunku 15.4
pokazano wyglÈd takiej aktywnoĂci.
W aplikacjach na tablety czÚsto stosuje siÚ pewien wzorzec. Po lewej stronie
ekranu wyĂwietla siÚ przewijanÈ listÚ, a po prawej — szczegóïowe informacje
o wybranym elemencie. Na rysunku 15.5 pokazano, ĝe wybranie elementu z listy
prowadzi do zmiany danych wyĂwietlanych w duĝym obszarze ze szczegóïami.
WróÊmy do problemu, czyli wyĂwietlania róĝnych komponentów w zaleĝ-
noĂci od orientacji tabletu. Na rysunku 15.6 widaÊ, co siÚ dzieje po obróceniu
urzÈdzenia.
Porównaj rysunki 15.5 i 15.6. WidaÊ, ĝe obszar ze szczegóïowymi informa-
cjami wyglÈda tak samo w obu orientacjach. Róĝnice sÈ podobne do tych, które
znamy z aplikacji na smartfony. Jednak listy ofert wyglÈdajÈ inaczej. Tego wïaĂnie
dotyczy okreĂlenie „zupeïnie odmienne ukïady” z opisu problemu. W smart-
fonach takie podejĂcie stosuje siÚ bardzo rzadko, jednak w aplikacjach na tablety
nie jest ono niczym niezwykïym.
0
TECHNIKA 89. Fragmenty
643
Rysunek 15.4. Lista ofert i szczegóáowe informacje w ukáadzie poziomym
Rysunek 15.5. Przeglądanie elementów z listy ofert
Najwaĝniejszym mechanizmem przy tworzeniu aplikacji podobnych do pokazanej
sÈ fragmenty. UmoĝliwiajÈ one podziaï interfejsu uĝytkownika na moduïy. Na lis-
tingu 15.2 przedstawiono kod ukïadu z rysunku 15.4.
644
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
Rysunek 15.6. Lista ofert
i szczegóáowe informacje
w ukáadzie pionowym
Listing 15.2. Kod XML ukáadu ze szczegóáowymi informacjami o ofercie
(/res/layout/details.xml)
?xml version= 1.0 encoding= utf-8 ?
LinearLayout xmlns:android= http://schemas.android.com/apk/res/android
android:orientation= horizontal
android:layout_width= match_parent
android:layout_height= match_parent
android:id= @+id/details_container
fragment
class= com.manning.aip.tabdroid.SectionDetailsFragment
android:id= @+id/section_list_fragment
android:visibility= gone
android:layout_marginTop= ?android:attr/actionBarSize
android:layout_width= 300dp
android:layout_height= match_parent /
fragment class= com.manning.aip.tabdroid.DealFragment
android:id= @+id/deal_fragment
android:layout_width= match_parent
android:layout_height= match_parent /
/LinearLayout
0
TECHNIKA 89. Fragmenty
645
Mamy nadziejÚ, ĝe miïym zaskoczeniem jest dla Ciebie to, jak prosty jest plik
ukïadu dla widoku ze szczegóïowymi informacjami. Kod obejmuje dwa frag-
menty. Pierwszy
poka-
zuje szczegóïowe informacje na temat wybranego elementu. Kod pierwszego
fragmentu przedstawiono na listingu 15.3.
wyĂwietla listÚ ofert po prawej stronie ekranu. Drugi
Listing 15.3. Fragment wyĞwietlający listĊ ofert (plik SectionDetailsFragment.java)
public class SectionDetailsFragment extends ListFragment {
Section section;
int currentPosition = 0;
DealsApp app;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
app = (DealsApp) this.getActivity().getApplication();
section = app.currentSection;
if (savedInstanceState != null){
currentPosition = savedInstanceState.getInt( currentPosition );
int savedSectionPos =
savedInstanceState.getInt( currentSection , -1);
if (savedSectionPos = 0){
section = app.sectionList.get(savedSectionPos);
app.currentSection = section;
}
} else if (app.currentItem != null){
for (int i=0;i section.items.size();i++){
if (app.currentItem.equals(section.items.get(i))){
currentPosition = i;
break;
}
}
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
buildUi();
}
private void buildUi(){
ListView listView = this.getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
String[] dealTitles = new String[section.items.size()];
int i = 0;
for (Item item : section.items){
dealTitles[i++] = item.title;
}
setListAdapter(new ArrayAdapter String (getActivity(),
R.layout.deal_title_list_entry, dealTitles));
listView.setSelection(currentPosition);
showDeal(currentPosition);
}
}
646
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
Aby utworzyÊ fragment, wystarczy utworzyÊ klasÚ pochodnÈ od android.app.
´Fragment. Tu tworzymy klasÚ pochodnÈ od ListFragment
, która sama jest
klasÈ pochodnÈ od klasy Fragment. Klasa ListFragment obejmuje jeden widok
ListView i czÚsto sïuĝy do wyĂwietlania list elementów w ukïadzie z podzielonym
ekranem, takim jak na rysunku 15.4. Fragment ma odrÚbny cykl ĝycia powiÈzany
z cyklem ĝycia nadrzÚdnej aktywnoĂci. AktywnoĂÊ ta ĝÈda widoku od fragmentu
przez wywoïanie metody onCreateView danego fragmentu. Metoda onCreate
fragmentu jest wywoïywana bezpoĂrednio po wywoïaniu metody onCreate aktyw-
noĂci, jednak przed metodÈ onCreateView fragmentu. W metodzie onCreate przy-
wracamy lub ustawiamy stan fragmentu (podobnie jak robimy z aktywnoĂciÈ).
Pewien czas po wywoïaniu metody onCreateView fragmentu nastÚpuje wywoïanie
metody onActivityCreated
. Jak wskazuje nazwa, wywoïanie to ma miejsce
po utworzeniu aktywnoĂci. We wspomnianej metodzie konfigurujemy widok
bÚdÈcy czÚĂciÈ fragmentu ListFragment. Widok ten dziaïa jak inne
ListView
widoki ListView, dlatego trzeba okreĂliÊ dla niego adapter ListAdapter
, który
zapewni dane i ukïad elementów z widoku.
Warto zauwaĝyÊ, ĝe ostatniÈ operacjÈ w ramach konfigurowania interfejsu
uĝytkownika fragmentu ListFragment jest wywoïanie metody showDeal. Metoda
ta wyĂwietla konkretnÈ ofertÚ w gïównym fragmencie ze szczegóïowymi infor-
macjami. Dlatego metodÚ tÚ naleĝy wywoïywaÊ po wybraniu elementu listy.
Na listingu 15.4 przedstawiono kod do wyĂwietlania ofert i obsïugi dotkniÚcia
elementu.
Listing 15.4. WyĞwietlanie konkretnej oferty (plik SectionDetailsFragment.java)
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
this.currentPosition = position;
showDeal(position);
}
private void showDeal(int position){
app.currentItem = app.currentSection.items.get(position);
DealFragment fragment =
(DealFragment) getFragmentManager().findFragmentById(
R.id.deal_fragment);
fragment.showCurrentItem();
}
Jednym z wygodnych aspektów korzystania z klasy ListFragment jest to, ĝe trzeba
przesïoniÊ metodÚ onListItemClick, aby obsïugiwaÊ dotkniÚcie elementów listy.
. NastÚpnie wywoïujemy metodÚ
Tu sprawdzamy wybrany element listy
showDeal z listingu 15.3. Drugi fragment ma wtedy wyĂwietliÊ innÈ ofertÚ, dla-
tego potrzebny jest uchwyt do tego fragmentu
. Do pobrania uchwytu uĝywamy
egzemplarza klasy FragmentManager, dostÚpnego w kaĝdym fragmencie. WróÊ do
listingu 15.2. ZwróÊ uwagÚ, ĝe przypisaliĂmy do fragmentu identyfikator, który
0
TECHNIKA 89. Fragmenty
647
moĝna teraz wykorzystaÊ do uzyskania uchwytu. Po jego pobraniu naleĝy wywo-
ïaÊ metodÚ showCurrentItem
, aby nakazaÊ ponowne wyĂwietlenie fragmentu.
Na listingu 15.5 przedstawiono tÚ metodÚ i pozostaïy kod klasy DealFragment.
Listing 15.5. Fragment do wyĞwietlania ofert (plik DealFragment.java)
public class DealFragment extends Fragment {
DealsApp app;
private ProgressBar progressBar;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
app = (DealsApp) getActivity().getApplication();
View dealView = inflater.inflate(R.layout.deal_details,
container,
false);
progressBar = (ProgressBar) dealView.findViewById(R.id.progress);
progressBar.setIndeterminate(true);
Item item = app.currentItem;
if (item != null) {
populateDealView(dealView, item);
}
return dealView;
}
private void populateDealView(View dealView, Item item) {
ImageView icon = (ImageView) dealView.findViewById(
R.id.details_icon);
icon.setImageResource(R.drawable.placeholder);
new RetrieveImageTask(icon).execute(item.picUrl);
TextView title =
(TextView) dealView.findViewById(R.id.details_title);
title.setText(item.title);
CharSequence pricePrefix =
getText(R.string.deal_details_price_prefix);
TextView price =
(TextView) dealView.findViewById(R.id.details_price);
price.setText(pricePrefix + item.convertedCurrentPrice);
TextView msrp = (TextView) dealView.findViewById(
R.id.details_msrp);
msrp.setText(item.msrp);
TextView quantity =
(TextView) dealView.findViewById(R.id.details_quantity);
quantity.setText(Integer.toString(item.quantity));
TextView quantitySold = (TextView) dealView.findViewById(
R.id.details_quantity_sold);
quantitySold.setText(Integer.toString(item.quantitySold));
TextView location =
(TextView) dealView.findViewById(R.id.details_location);
location.setText(item.location);
}
public void showCurrentItem(){
Item item = app.currentItem;
View dealView = getView();
populateDealView(dealView, item);
}
}
648
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
To kolejny fragment. Tym razem bezpoĂrednio tworzymy klasÚ pochodnÈ od klasy
Fragment
. Nie trzeba przejmowaÊ siÚ zarzÈdzaniem stanem tego fragmentu,
poniewaĝ jest on powiÈzany ze stanem aktywnoĂci (i fragmentu ListFragment
z listingu 15.3). Dlatego wystarczy przesïoniÊ metodÚ onCreateView
. Zauwaĝ, ĝe
do tej wywoïywanej zwrotnie metody przekazujemy obiekt klasy LayoutInflater.
. NastÚpnie
Wykorzystujemy go do przeksztaïcenia pliku XML ukïadu na widok
dane wybranej oferty z kontrolkami z pliku XML ukïadu. W koñco-
wiÈĝemy
wej czÚĂci listingu znajduje siÚ metoda showCurrentItem, którÈ mogÈ wywoïywaÊ
inne fragmenty. Metoda ta sprawdza, który element jest wybrany, i przekazuje
go do uĝywanej juĝ wczeĂniej metody populateDealView
.
Po zmianie orientacji tabletu na pionowÈ naleĝy wyĂwietliÊ inny ukïad,
widoczny na rysunku 15.6. NajproĂciej uzyskaÊ ten efekt przez zastosowanie
odrÚbnego pliku XML ukïadu. Kod ukïadu dla orientacji pionowej przedsta-
wiono na listingu 15.6.
Listing 15.6. Ukáad dla orientacji pionowej (/res/layout-port/details.xml)
?xml version= 1.0 encoding= utf-8 ?
LinearLayout xmlns:android= http://schemas.android.com/apk/res/android
android:orientation= vertical
android:layout_width= match_parent
android:layout_height= match_parent
android:id= @+id/details_container
android:gravity= bottom
fragment class= com.manning.aip.tabdroid.DealFragment
android:id= @+id/deal_fragment
android:layout_marginTop= ?android:attr/actionBarSize
android:layout_width= match_parent
android:layout_height= wrap_content
/
fragment class= com.manning.aip.tabdroid.FilmstripFragment
android:id= @+id/section_filmstrip_fragment
android:layout_width= match_parent
android:layout_height= 300dp
android:layout_gravity= bottom
/
/LinearLayout
Kod z listingu 15.6 jest podobny do kodu z listingu 15.2. Ponownie wykorzystu-
opisany juĝ fragment DealFragment. Przeznaczeniem fragmentów jest
jemy tu
wïaĂnie umoĝliwianie powtórnego wykorzystania kodu. Zauwaĝ, ĝe nie pokazu-
jemy kodu aktywnoĂci obejmujÈcej fragmenty. Nie ma takiej potrzeby. Fragmenty
sÈ niezaleĝne. W orientacji pionowej zastÚpujemy klasÚ SectionDetailsFragment
klasÈ FilmstripFragment
. Kod tej ostatniej znajduje siÚ na listingu 15.7.
Klasa FilmstripFragment jest nieco podobna do klasy SectionDetailsFragment
z listingu 15.3. Obie klasy wyĂwietlajÈ wszystkie oferty z danej kategorii i umoĝ-
liwiajÈ dotkniÚcie oferty w celu wyĂwietlenia szczegóïowych informacji na jej
0
TECHNIKA 89. Fragmenty
649
Listing 15.7. Pozioma lista rysunków uĪywana do wybierania ofert
(plik FilmstripFragment.java)
public class FilmstripFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Kod do zarządzania stanem pominiĊto.
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
HorizontalScrollView strip =
(HorizontalScrollView) inflater.inflate(R.layout.filmstrip,
container,
false);
fillWithPics(strip);
return strip;
}
private void fillWithPics(HorizontalScrollView strip) {
ViewGroup pics = (ViewGroup) strip.findViewById(R.id.pics);
if (pics.getChildCount() 0){
pics.removeAllViews();
}
int i =0;
for (Item item : section.items){
ImageView imgView = new ImageView(getActivity());
// Kod do pobierania bitmapy.
imgView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View img) {
currentPosition = pos;
showDeal(pos);
}
});
}
showDeal(currentPosition);
}
private void showDeal(int position){
app.currentItem = app.currentSection.items.get(position);
DealFragment fragment = (DealFragment) getFragmentManager()
.findFragmentById(R.id.deal_fragment);
fragment.showCurrentItem();
}
}
temat w komponencie DealFragment. Podobny mechanizm stosujemy w innych
fragmentach. Najpierw w metodzie onCreate
przywracamy stan. Dalej znajduje
siÚ implementacja metody onCreateView
, która przeksztaïca plik XML ukïadu
w zwracany widok. Tym razem nie stosujemy widoku ListView, ale „rolkÚ filmu” —
przewijany w poziomie zbiór rysunków (jest to widok HorizontalScrollView;
zobacz plik /res/layout-port/filmstrip.xml). Wystarczy zapeïniÊ ten widok
obiek-
tami klasy ImageView, obejmujÈcymi bitmapy z rysunkami ofert. Dla kaĝdego
widoku ImageView trzeba ustawiÊ metodÚ obsïugi zdarzeñ
wywoïywanÈ w reakcji
650
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
na dotkniÚcie grafiki przez uĝytkownika. Zdarzenie to prowadzi do pobrania za
pomocÈ klasy FragmentManager uchwytu do fragmentu DealFragment i wywoïania
metody showCurrentItem tego fragmentu
.
OMÓWIENIE
Fragmenty umoĝliwiajÈ porzÈdkowanie kodu aplikacji w nowy sposób. Fragment
pod wieloma wzglÚdami moĝe byÊ „samowystarczalny”. Samodzielnie zarzÈdza
wyĂwietlanymi danymi i obsïuguje swój stan. Fragmenty z przykïadowej aplikacji
zaleĝÈ od globalnego stanu aplikacji (obiektu typu Application). Moĝna z nich
korzystaÊ w dowolnym miejscu omawianego programu, ale juĝ nie poza nim. Jest
to celowe. Inna moĝliwoĂÊ to utworzenie fragmentów zaleĝnych od usïug lub
caïkowicie niezaleĝnych.
ProgramiĂci stosowali ten wzorzec na dïugo przed wprowadzeniem frag-
mentów, choÊ framework Androida tego nie uïatwiaï. Jedno z czÚsto uĝywanych
podejĂÊ polegaïo na tworzeniu komponentów interfejsu uĝytkownika, które
potrafiÈ zarzÈdzaÊ stanem, pobieraÊ dane i wykonywaÊ podobne operacje. OdmianÈ
tego wzorca jest rozwijanie komponentów interfejsu uĝytkownika bezpoĂrednio
komunikujÈcych siÚ z usïugÈ wykonujÈcÈ wszystkie skomplikowane operacje.
ChoÊ zdaniem niektórych programistów naleĝy unikaÊ takich rozwiÈzañ, ponie-
waĝ naruszajÈ paradygmat model-widok-kontroler, opisane wzorce czÚsto oka-
zujÈ siÚ przydatne. Zaïóĝmy, ĝe w aplikacji znajduje siÚ nagïówek z informa-
cjami o stanie, na przykïad o liczbie nieprzeczytanych wiadomoĂci lub nowych
ofert dnia. Przed wprowadzeniem fragmentów czÚsto (oprócz ïÈczenia kodu modelu
z kodem komponentu interfejsu uĝytkownika) tworzono klasÚ aktywnoĂci do
zarzÈdzania stanem. NastÚpnie aktywnoĂÊ tÚ stosowano jako klasÚ bazowÈ dla
wszystkich pozostaïych aktywnoĂci aplikacji. RozwiÈzania te majÈ wady i zalety,
przy czym fragmenty pozwalajÈ pisaÊ duĝo bardziej przejrzysty kod, niĝ jest to
w przypadku innych podejĂÊ.
Technika oparta na bazowej aktywnoĂci czÚsto sïuĝy teĝ do obsïugi menu.
Taka aktywnoĂÊ moĝe tworzyÊ menu wyĂwietlane we wszystkich aktywnoĂciach.
Jednym z powodów tworzenia menu na poziomie aplikacji jest to, ĝe zazwyczaj
ma ono dla programisty niewielkie znaczenie. JeĂli w menu znajduje siÚ jakaĂ
waĝna opcja, i tak trzeba umieĂciÊ jÈ takĝe w innym miejscu ekranu, poniewaĝ
bywa, ĝe uĝytkownicy nie korzystajÈ z menu. W menu nierzadko znajdujÈ siÚ teĝ
typowe opcje, takie jak O programie, Pomoc techniczna, Wyrejestruj siÚ itd.
W wersji Honeycomb wprowadzono rozwiÈzanie znacznie wygodniejsze od
menu — pasek akcji (ang. Action Bar). W nastÚpnej technice opisujemy ten mecha-
nizm i wyjaĂniamy, kiedy warto go stosowaÊ.
0
TECHNIKA 90. Pasek akcji
Warto stosowaÊ menu w Androidzie. Moĝna umieĂciÊ w nim wiele skrótów
i przydatnych opcji. Moĝna teĝ udostÚpniaÊ w nim operacje kontekstowe. Powaĝ-
nym problemem jest jednak to, ĝe uĝytkownicy rzadko zaglÈdajÈ do menu.
0
TECHNIKA 90. Pasek akcji
651
Wskutek tego zaczÚto tworzyÊ paski akcji. CzÚsto stosuje siÚ je w tym samym
celu co samo menu, sÈ jednak skuteczniejsze z uwagi na wiÚkszÈ widocznoĂÊ dla
uĝytkownika.
PROBLEM
Chcemy wyĂwietlaÊ dodatkowe, ale uĝyteczne funkcje dostÚpne w kontekĂcie
uĝywanej akurat aktywnoĂci. Nie zamierzamy jednak stosowaÊ standardowego
menu Androida, poniewaĝ uĝytkownicy czÚsto nie korzystajÈ z niego.
ROZWIĄZANIE
RozwiÈzanie polega na zastosowaniu paska akcji. Znajduje siÚ on w górnej czÚĂci
ekranu i jest dobrze widoczny dla uĝytkowników. Eliminuje to najwiÚkszy kïopot
zwiÈzany z menu. Na rysunku 15.7 pokazano przykïadowy pasek akcji w aplikacji
na tablety.
Rysunek 15.7. Pasek akcji w akcji
Jak widaÊ, pasek akcji znajduje siÚ w górnej czÚĂci ekranu. W przykïadowym
programie na pasku sÈ ikona aplikacji, kilka zakïadek i przycisk Podziel siÚ.
Ikona aplikacji pozwala uĝytkownikom przejĂÊ do gïównego ekranu, a zakïadki
sïuĝÈ do przechodzenia do róĝnych kategorii ofert dnia z eBaya. Na rysunku 15.8
pokazano, ĝe przycisk Podziel siÚ pozwala „podzieliÊ siÚ” ofertÈ z innymi osobami
za pomocÈ aplikacji zainstalowanych w urzÈdzeniu.
Jak moĝe pamiÚtasz, w pierwszej wersji aplikacji DealDroid funkcja „dzie-
lenia siÚ” byïa ukryta w menu. W wersji dla tabletów nawigacja jest wygodniejsza.
Pasek akcji nie tylko pozwala rozwiÈzaÊ problem z menu, ale ma teĝ inne funkcje.
Zakïadki nawigacyjne omawiamy dalej. Teraz skupimy siÚ na ikonach aplikacji
i funkcji „dzielenia siÚ”. Na listingu 15.8 przedstawiono kod tych elementów.
Listing 15.8. Ikona aplikacji i funkcji „dzielenia siĊ” z paska akcji
(plik DetailsActivity.java)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.details_menu, menu);
return true;
}
652
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
Rysunek 15.8. „Dzielenie siĊ” ofertą na tablecie
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, DealsMain.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.share_action:
shareDealUsingChooser( text/* );
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void shareDealUsingChooser(final String type) {
// Z uwagi na zwiĊzáoĞü pominiĊto. Kod jest taki sam jak w rozdziale 2.
}
private String createDealMessage() {
// Z uwagi na zwiĊzáoĞü pominiĊto.
}
Na listingu 15.8 widaÊ, ĝe przodkiem paska akcji jest menu. Aby utworzyÊ pasek
akcji, naleĝy zaimplementowaÊ wywoïywanÈ zwrotnie metodÚ onCreateOptionsMenu
aktywnoĂci
. Elementy paska akcji moĝna tworzyÊ programowo. Jest to przy-
datne zwïaszcza wtedy, gdy wyĂwietlanie elementów zaleĝy od stanu aktywnoĂci.
Inna moĝliwoĂÊ to okreĂlenie zawartoĂci paska akcji w XML-u. Oto kod w XML-u
tworzÈcy pasek akcji z rozdziaïu 15.7:
0
TECHNIKA 90. Pasek akcji
653
menu xmlns:android= http://schemas.android.com/apk/res/android
item android:id= @+id/share_action
android:title= @string/deal_details_share_menu
android:icon= @drawable/ic_menu_share
android:showAsAction= ifRoom|withText /
/menu
Jak widaÊ, okreĂlony jest tu jeden element z tytuïem i ikonÈ. W przykïadzie
tytuï i ikona to zewnÚtrzne zasoby, dlatego moĝna utworzyÊ ich wersje dla innych
jÚzyków. ZwróÊ teĝ uwagÚ na atrybut showAsAction. Pojawiï siÚ on w Androidzie 3.0
i sïuĝy do okreĂlenia, kiedy dana opcja menu ma byÊ dostÚpna jako akcja i jak ma
wyglÈdaÊ. Moĝna ustawiÊ ten atrybut na always, jednak jeĂli na ekranie brakuje
miejsca, pasek wyglÈda nieelegancko.
WróÊmy do listingu 15.8. Aby zdefiniowaÊ dziaïanie paska akcji (reakcjÚ
na dotkniÚcie opcji przez uĝytkownika), naleĝy zaimplementowaÊ metodÚ
onOptionsItemSelected aktywnoĂci. W ten sam sposób okreĂlana jest reakcja na
. Ikona ta jest
dotkniÚcie ikony aplikacji, widocznej po lewej stronie paska
identyfikowana na podstawie predefiniowanego identyfikatora zasobu (home).
Aplikacja w reakcji na wybranie tej ikony opróĝnia stos aktywnoĂci i kieruje uĝyt-
. DotkniÚcie przycisku Podziel siÚ moĝna wykryÊ
kownika do gïównego ekranu
przez dopasowanie identyfikatora zdefiniowanego w XML-owym kodzie menu do
identyfikatora wybranego elementu MenuItem
. Wybranie wspomnianego przy-
cisku prowadzi do wywoïania metody shareDealUsingChooser z aplikacji Deal-
Droid z rozdziaïu 2. Aplikacja wyĂwietla wtedy interfejs uĝytkownika widoczny
na rysunku 15.8.
Wiesz juĝ, jak tworzyÊ ikony i okreĂlaÊ ich dziaïanie. Przyjrzyjmy siÚ teraz,
jak tworzyÊ zakïadki widoczne na rysunku 15.7. Potrzebny kod pokazano na
listingu 15.9.
Listing 15.9. Tworzenie zakáadek paska akcji i zarządzanie nimi
(plik DetailsActivity.java)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
app = (DealsApp) getApplication();
ActionBar bar = this.getActionBar();
TabListener listener = new TabListener(){
@Override
public void onTabReselected(Tab t, FragmentTransaction txn) {}
@Override
public void onTabSelected(Tab t, FragmentTransaction txn) {
if (active){
changeTab(t.getPosition());
}
}
@Override
public void onTabUnselected(Tab t, FragmentTransaction txn) {}
};
for (int i=0;i Math.min(6, app.sectionList.size());i++){
654
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
final Section section = app.sectionList.get(i);
Tab tab = bar.newTab();
tab.setText(chomp(section.title));
tab.setTabListener(listener);
if (app.currentSection != null
app.currentSection.equals(section)){
bar.addTab(tab, true);
} else {
bar.addTab(tab);
}
}
bar.setDisplayShowTitleEnabled(false);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
active = true;
}
private void changeTab(int position){
FragmentManager fm = getFragmentManager();
int orientation = getResources().getConfiguration().orientation;
if (orientation == ORIENTATION_LANDSCAPE){
SectionDetailsFragment fragment =
(SectionDetailsFragment) fm.findFragmentById(
R.id.section_list_fragment);
fragment.setSection(position);
} else {
FilmstripFragment fragment =
(FilmstripFragment) fm.findFragmentById(
R.id.section_filmstrip_fragment);
fragment.setSection(position);
}
}
Od wersji Android 3.0 kaĝda aktywnoĂÊ moĝe mieÊ pasek akcji. Jest on dostÚpny
poprzez metodÚ getActionBar aktywnoĂci
. Pomysï polega na programowym
tworzeniu zakïadek i dodawaniu ich do paska akcji. Kaĝda zakïadka wymaga
odbiornika TabListener, który bÚdzie reagowaï na dotkniÚcie, dlatego tworzymy
jeden taki odbiornik do obsïugi wszystkich zakïadek. Dalej znajduje siÚ imple-
mentacja metody onTabSelected
i wywoïanie metody changeTab na podstawie
pozycji wybranej zakïadki. Dziaïanie metody changeTab omawiamy dalej.
Kiedy egzemplarz odbiornika TabListener jest juĝ gotowy, moĝna utworzyÊ
, ustawiamy
zakïadki i dodaÊ je do paska akcji. Programowo tworzymy zakïadkÚ
jej tytuï i odbiornik TabListener
. Zauwaĝ, ĝe na podstawie kategorii wybranej
przez uĝytkownika aplikacja okreĂla obecnie zaznaczonÈ zakïadkÚ. Nakazujemy
teĝ paskowi akcji, aby nie wyĂwietlaï nazwy aktywnoĂci, a w zamian pokazywaï
zakïadki nawigacyjne.
Przyjrzyjmy siÚ teraz metodzie changeTab wywoïywanej przez zwrotnÈ metodÚ
onTabSelected odbiornika TabListener. Metoda changeTab najpierw sprawdza orien-
. Jest to potrzebne, poniewaĝ ukïad tabletu wpïywa na zawar-
tacjÚ urzÈdzenia
toĂÊ aktywnoĂci. Metoda wykorzystuje informacjÚ o orientacji i obiekt klasy
FragmentManager z aktywnoĂci do uzyskania uchwytu do wyĂwietlanego fragmentu.
, co pozwala okreĂliÊ, jakiego
NastÚpnie ustawiamy kategoriÚ dla fragmentu
rodzaju oferty dnia majÈ byÊ widoczne.
0
TECHNIKA 91. PrzeciÈganie
655
OMÓWIENIE
Nawigacja z wykorzystaniem zakïadek nie jest niczym nowym ani specjalnym
dla tabletów. Od lat jest powszechnie uĝywana w aplikacjach sieciowych i wystÚ-
puje w Androidzie od wersji 1.0. Do tworzenia zakïadek zawsze sïuĝyïy klasy
TabHost i TabWidget. Pierwsza z nich umoĝliwia tworzenie zestawu zakïadek,
z których kaĝda powiÈzana jest z wyĂwietlanÈ aktywnoĂciÈ. Zakïadki paska akcji
to rozwiniÚcie tej techniki, podobnie jak inne aspekty tego paska sÈ rozwiniÚciem
menu.
Aby zbudowaÊ nawigacjÚ opartÈ na zakïadkach z paska akcji, naleĝy utworzyÊ
zakïadki w podobny sposób jak w klasie TabHost. Jednak zamiast ïÈczyÊ z kaĝdÈ
zakïadkÈ odrÚbnÈ aktywnoĂÊ, moĝna pracowaÊ w ramach jednej aktywnoĂci
i stosowaÊ fragmenty. W przykïadzie zmieniamy zawartoĂÊ fragmentu. ZwróÊ
jednak uwagÚ na to, ĝe do metody onTabSelected przekazywany jest obiekt klasy
FragmentTransaction. Dlatego w aktywnoĂci moĝna wykonywaÊ róĝne operacje na
fragmentach, na przykïad usuwaÊ je lub zastÚpowaÊ innymi. Pasek akcji nie tylko
jest ulepszeniem dawnego systemu menu, ale w poïÈczeniu z fragmentami
sprawia teĝ, ĝe porzÈdkowanie kodu aplikacji jest prostsze, i daje przy tym wiÚcej
moĝliwoĂci.
Ostatnia z podstawowych technik zwiÈzanych z tabletami, przeciÈganie,
pozwala usprawniÊ interakcjÚ uĝytkowników z aplikacjÈ.
TECHNIKA 91. Przeciąganie
OdkÈd Douglas Engelbart wymyĂliï mysz komputerowÈ, menedĝerowie produktu
ĝÈdajÈ od programistów dodawania funkcji przeciÈgania. W rozbudowanych
frameworkach do tworzenia aplikacji desktopowych mechanizm przeciÈgania
jest dostÚpny od wielu lat. W aplikacjach sieciowych przez dïugi czas wystÚpo-
waïy znaczne problemy z jego obsïugÈ. PracÚ programistom uïatwiaïy frame-
worki JavaScriptu, aĝ w koñcu mechanizm przeciÈgania staï siÚ czÚĂciÈ specyfi-
kacji jÚzyka HTML5. W Ăwiecie urzÈdzeñ mobilnych do momentu pojawienia siÚ
Androida 3.0 przeciÈganie byïo w frameworkach pomijane. OczywiĂcie, moĝna
byïo dodaÊ jego obsïugÚ za pomocÈ interfejsów API do obsïugi dotkniÚÊ, jed-
nak technikÚ tÚ wykorzystywano gïównie w grach. Od wersji Honeycomb prze-
ciÈganie moĝna stosunkowo ïatwo dodaÊ do aplikacji dowolnego rodzaju.
PROBLEM
Chcemy umoĝliwiÊ uĝytkownikom bardziej intuicyjnÈ interakcjÚ z aplikacjÈ
przez udostÚpnienie przeciÈgania róĝnych elementów.
ROZWIĄZANIE
Aby umoĝliwiÊ przeciÈganie w aplikacji, wystarczy zastosowaÊ kilka interfejsów
API wprowadzonych w Androidzie 3.0. W ramach przykïadu przedstawiamy
prostÈ aplikacjÚ z funkcjÈ przeciÈgania. Program wyĂwietla na ekranie widoki
0
656
ROZDZIAà 15. Pisanie aplikacji na tablety z Androidem
StackView (jest to nowa kontrolka wprowadzona w wersji Honeycomb) i umoĝliwia
uĝytkownikom zmianÚ uporzÈdkowania tych kontrolek przez ich przeciÈgniÚcie.
WyglÈd aplikacji przedstawiono na rysunku 15.9.
Rysunek 15.9. Aplikacja z funkcją przeciągania
Jak widaÊ, aplikacja wyĂwietla prostÈ siatkÚ z kilkoma kontrolkami StackView.
Na listingu 15.10 znajduje siÚ kod tego ukïadu.
Listing 15.10. Plik XML z ukáadem z siatką, uĪywanym przez mechanizm
przeciągania
?xml version= 1.0 encoding= utf-8 ?
TableLayout
xmlns:android= http://schemas.android.com/apk/res/android
android:layout_width= match_parent
android:layout_height= match_parent
TableRow
LinearLayout android:layout_width= 640dp
android:layout_height= 345dp
android:id= @+id/topLeft
StackView android:id= @+id/stack
android:layout_width= 250dp
android:layout_height= 250dp
android:clickable= true
android:loopViews= true
android:longClickable= true
/
/LinearLayout
LinearLayout android:layout_width= 640dp
android:layout_height= 345dp
android:id= @+id/topRight
/
/TableRow
TableRow
0
TECHNIKA 91. PrzeciÈganie
657
LinearLayout android:layout_width= 640dp
android:layout_height= 345dp
android:id= @+id/bottomLeft
/
LinearLayout android:layout_width= 640dp
android:layout_height= 345dp
android:id= @+id/bottomRight
StackView android:id= @+id/stack2
android:layout_width= 250dp
android:layout_height= 250dp
android:clickable= true
android:loopViews= true
android:longClickable= true
/
/LinearLayout
/TableRow
/TableLayout
W kodzie z listingu 15.10 uĝywamy ukïadu TableLayout
.
Pobierz darmowy fragment (pdf)