Stručný obsah Úvod
15
1. Nástroje pro vývoj
17
2. Anatomie Androidu
65
3. Anatomie aplikace
79
4. Škálovatelný design
121
5. Uživatelské rozhraní a události
135
6. Fragmenty
173
7. Aktivity a intenty
197
8. Interakce s uživatelem
209
9. Seznamy objektů
257
10. Databáze a práce s údaji
309
11. Grafika
371
12. Multimédia
407
13. Senzory a komunikace
431
14. Mapy a navigace
461
15. Sociální sítě
487
16. Cloudové služby
509
17. Služby a Broadcasty
543
18. Poskytování obsahu
551
19. Vývoj pro nositelná zařízení
573
20. Novinky verze 7.0 Nougat
595
21. Publikování aplikací do aplikačního obchodu Google Play
615
Rejstřík
K2301_blok.indd 3
633
23.5.2017 13:18:37
K2301_blok.indd 4
23.5.2017 13:18:37
Obsah Úvod
15
Kapitola 1
Nástroje pro vývoj Instalace Javy Instalace vývojového prostředí Android Studio První spuštění a konfigurace Android Studia Průběžná aktualizace Vytvoření projektu aplikace Odemknutí zařízení pro vývoj Spuštění aplikace na reálném zařízení Monitorování spuštěné aplikace
Seznámení se s vývojovým prostředím Editor kódu v jazyce Java Java pro migranty Gradle
Možnosti současného hardwaru Referenční zařízení Vytvoření emulátoru GitHub Vytvoření účtu Vytvoření repozitáře Vytvoření větve (branch) Úprava souborů
17 17 20 22 26 27 35 36 38
39 46 48 49
52 52 54 57 58 60 62 63
Kapitola 2
Anatomie Androidu
K2301_blok.indd 5
65
Multiplatformní operační systém Historie verzí Starší verze Android 5.0 Lollipop Android 6.0 Marshmallow Android 7.0 Nougat Stručně o architektuře Androidu
65 66 66 68 70 72 74
Linux Kernel Hardware Abstraction Layer (HAL)
75 75
23.5.2017 13:18:37
OBSAH
6
Nativní knihovny Android Runtime – ART Java API Framework Aplikace
76 76 76 77
Kapitola 3
Anatomie aplikace Dříve než začnete vyvíjet – filozofie aplikace Základní součásti aplikace pro Android Aktivity (Activity) Služby (Services) Broadcast receivers Poskytovatelé obsahu (Content providers)
Aktivita a její životní cyklus Životní cyklus aktivity onCreate() onStart() a onResume() onPause() onStop() onDestroy()
Příklad – životní cyklus aktivity Příklad – ukládání a obnovení stavu aktivity Intent Odevzdávání údajů a výsledků Intent Filter
Příklad – Anatomie projektu Vytvoření projektu Výběr cílové platformy Výběr typu hlavní aktivity Složky a soubory tvořící projekt Jednoduchý vizuální návrh uživatelského rozhraní Morphing – změna typu prvku
Definice uživatelského rozhraní Uživatelské rozhraní aplikace na různých zařízeních Aplikační kód
Odstranění tlačítka FloatingActionButton z Basic Activity
Definice objektů ve zdrojích (resources) Textové řetězce Pole řetězců Množné číslo podstatných jmen Modifikátory
Aplikační manifest Identifikační grafika aplikace
K2301_blok.indd 6
79 79 83 83 84 84 84
84 86 87 87 87 88 88
88 91 92 93 94
96 96 98 99 100 103 106
107 109 111
113
113 115 115 115 116
117 119
23.5.2017 13:18:37
OBSAH
7
Kapitola 4
Škálovatelný design Designový styl Material Přizpůsobení rozlišení obrazovky Metrika designu Pravidlo násobků rozměrů
Variabilita zařízení a obrazovek
121 121 125 127 131
131
Kapitola 5
Uživatelské rozhraní a události
135
Návrh uživatelského rozhraní Kontejnery na rozmístění prvků
136 137
LinearLayout RelativeLayout FrameLayout TableLayout GridLayout AbsoluteLayout CoordinatorLayout Vnoření kontejnerů ScrollView
137 139 142 143 145 147 147 148 150
Příklad – definice rozložení prvků
151
Obsluha události Obsluha událostí ve vizuálním návrhu
156 159
Příklad – spuštění jiné aktivity Aplikační logika Vytvoření nové aktivity
Ladění aplikace
161 162 165
169
Kapitola 6
Fragmenty Fragmenty
174
Životní cyklus fragmentu Statický a dynamický layout
175 176
Příklad 1 – změna orientace
178
1. Vytvoření layoutu fragmentů 2. Hlavní aktivita 3. Vytvoření tříd fragmentů 4. Úprava třídy hlavní aktivity 5. Test aplikace
Příklad 2 – hlavní aktivita využívající fragment Příklad 3 – aplikace se dvěma panely 1. Vytvoření layoutu fragmentů
K2301_blok.indd 7
173
178 179 180 181 182
182 185 185
23.5.2017 13:18:37
OBSAH
8
2. Hlavní aktivita 3. Vytvoření tříd fragmentů 4. Úprava třídy hlavní aktivity 5. Test aplikace
Příklad 4 – aplikace master-detail se dvěma panely 1. Zobrazované údaje 2. Hlavní aktivita 3. Kód fragmentu na zobrazení seznamu objektů 4. Kód fragmentu na zobrazení seznamu detailů 5. Aktivita na zobrazení detailu 6. Test aplikace
186 187 188 188
189 190 190 191 193 194 195
Kapitola 7
Aktivity a intenty Intent Explicitní intenty Příklad – explicitní Intenty
Implicitní Intenty Příklad – implicitní Intenty
197 197 197 200
204 205
Kapitola 8
Interakce s uživatelem Dotyky a gesta Příklad – zobrazení událostí dotyků Příklad – zobrazení vícenásobných dotyků Detekce standardně používaných gest Příklad – detekce gest Příklad – gesto pinch Příklad – univerzální počítadlo Příklad – využití vlastních gest aplikace Floating Action Button Nabídka funkcionality – menu Možnosti aplikační lišty App Bar Navigace pomocí menu Přizpůsobení a rozdělení lišty Action Bar Navigace na jinou aktivitu (a zpět)
Rozdělení obsahu na karty Skrývání aplikační lišty Využití vysouvacího panelu Navigation Drawer
K2301_blok.indd 8
209 209 211 214 218 219 221 223 226 230 232 233 234 239 240
242 248 250
23.5.2017 13:18:37
OBSAH
9
Kapitola 9
Seznamy objektů Jak to funguje? Třída ListActivity Příklad – ListActivity s formátovaným zobrazením položek Návrh uživatelského rozhraní Aplikační kód
Příklad – ListActivity s kontextovým menu položky Příklad ListView se statickými údaji v poli řetězců Návrh uživatelského rozhraní Aplikační kód
Příklad – ListView s údaji v kódu Návrh uživatelského rozhraní Aplikační kód
Příklad – výběr více položek ze seznamu Návrh uživatelského rozhraní Aplikační kód
Příklad – Zobrazení hierarchické struktury
257 257 259 263 263 265
267 270 270 271
272 272 272
273 274 276
279
Návrh uživatelského rozhraní Aplikační kód
279 281
Seznam objektů s obrázky
286
Návrh uživatelského rozhraní Aplikační kód
286 287
Příklad – Aktivita Master/Detail Flow Vytvoření projektu Struktura projektu Přizpůsobení
Přidání objektu do seznamu Seznamy objektů využívající RecyclerView a CardView RecyclerView CardView Příklad RecyclerView a CardView
291 291 293 294
298 301 301 302 302
Kapitola 10
Databáze a práce s údaji Ukládání údajů Třída SharedPreferences Příklad – uložení nejvyššího dosaženého skóre hry Příklad – PreferenceFragment
K2301_blok.indd 9
309 309 309 310 313
23.5.2017 13:18:37
OBSAH
10
Ukládání údajů do souboru Příklad – ukládání do souboru v interní paměti Příklad – ukládání do souboru v externí paměti
Ukládání dočasných souborů Databáze SQLite Pokusy se zabudovanou databází SQLite v emulátoru Interakce aplikace s databází Java třídy na přístup k SQLite databázi a jejím údajům
Příklad – čtenářský deník Rozbor řešení Datový model Vytvoření databázové tabulky Vkládání záznamů do databáze Aktualizace záznamů Vymazání záznamů Výběr údajů z databázové tabulky
Návrh uživatelského rozhraní Hlavní aktivita Aktivita na přidání záznamu Aktivita na editování existujícího záznamu
Programování aplikační logiky Hlavní aktivita Aktivita na přidání záznamu Aktivita na editování záznamu
Údaje z webu ve formátech JSON a XML Rozbor zadání Zdroj údajů pro aplikaci Návrh uživatelského rozhraní Aplikace na načítání údajů ve formátu JSON Aplikace na načítání údajů ve formátu XML Varianta využívající Document Object Model Varianta využívající XmlPullParser
Statická data ve formátu XML Aplikační kód
316 317 320
322 323 324 326 327
328 328 331 332 333 334 334 335
338 338 341 342
344 345 346 347
349 349 349 351 353 357 357 360
365 368
Kapitola 11
Grafika Zobrazení obrázku přes XML návrh Zobrazení obrázku programově Zobrazení obrázku z internetu Rozbor řešení Povolení přístupu k internetu Návrh uživatelského rozhraní Aplikační kód
K2301_blok.indd 10
371 372 373 375 375 375 375 376
23.5.2017 13:18:37
OBSAH
Základní grafické tvary – staticky Základní grafické tvary – dynamicky Vykreslování na Canvas Kreslení dotykem na Canvas Dynamické vykreslování na Canvas s využitím View Dynamické vykreslování na Canvas s využitím SurfaceView Animace Metody klasické animace Příklad animace TransitionDrawable Příklad animace AnimationDrawable Příklad animace Tween Property Animation Příklad na ilustraci principu fungování Property Animation Příklad komplexnějšího využití Property Animation
Animace prvků uživatelského rozhraní Příklad – animace přesunu tlačítek
11
377 379 381 382 384 387 390 391 391 392 394 396 398 399
401 402
Kapitola 12
Multimédia Příklad – přehrávání zvuku Příklad – přehrávání videa Příklad – nahrávání zvuku Příklad – Snímání fotografie I Příklad – Snímání fotografie II Příklad – Snímání fotografie s využitím externí aplikace Příklad – Nahrávání videa
407 408 412 414 418 423 426 427
Kapitola 13
Senzory a komunikace Integrované senzory smartphonů a tabletů Získávání údajů ze senzorů Identifikace senzoru a jeho možností (capabilities) Příklad – zobrazení údajů z akcelerometru Příklad – zobrazení filtrovaných údajů z akcelerometru Příklad – magnetický kompas Senzor osvětlení Náklonoměr
Snímač otisků prstů Komunikace přes Bluetooth
K2301_blok.indd 11
431 431 432 433 434 438 442 446 446
447 455
23.5.2017 13:18:38
OBSAH
12
Kapitola 14
Mapy a navigace
461
Lokalizační a mapové služby
461
Příklad – určení polohy zařízení Příklad – určení polohy zařízení
462 468
Zobrazení polohy na mapě Přípravné kroky Instalace Google Play Services
Úvodní příklad Vytvoření Google Maps API klíče
Příklad zobrazení polohy na mapě Příklad – Zobrazení polohy v jiné aplikaci schopné zobrazit mapy Příklad – zobrazení aktuální polohy na mapě
472 473 473
474 474
478 479 483
Kapitola 15
Sociální sítě Vytvoření aplikace využívající Facebook Facebook for developers Sdílení obsahu z aplikace na Facebooku Uživatelské rozhraní na sdílení obsahu na Facebook Vytvoření aplikace pro Android přihlašující se k Facebooku
Příklad aplikace na posílání statusů a obrázků
487 487 487 489 490 491
497
Kapitola 16
Cloudové služby Google Cloud Messaging Firebase Cloud Messaging
509 510
FCM zprávy Příklad na posílání zpráv
512 514
Konfigurace FCM
Přijímání notifikací na popředí Posílání zpráv přes Azure Notification Hub Vytvoření projektu v Android Studiu Vytvoření FCM Vytvoření Azure Notification Hub Přidání služby Google Play do projektu aplikace pro Android Aplikační logika v kódu v Javě
Připojení aplikace pro Android k mobilní službě Microsoft Azure Mobile Apps Vytvoření aplikace využívající službu Azure Mobile Apps Konfigurace služby
K2301_blok.indd 12
509
518
520 523 523 523 525 527 529
535 536 537 538
23.5.2017 13:18:38
OBSAH
13
Kapitola 17
Služby a broadcasty Služba a její životní cyklus Příklad – přehrávání hudby na pozadí
543 544 546
Kapitola 18
Poskytování obsahu Třída ContentProvider Ukládání kontaktů v zařízení s Androidem Příklad – přístup ke kontaktům v zařízení Příklad – přístup ke kontaktům, načítání údajů na pozadí Příklad – aktualizace údajů Příklad – vytvoření aplikace, která bude poskytovat údaje Příklad – vytvoření aplikace, která bude poskytovat údaje z databáze
551 551 553 553 558 559 562 565
Kapitola 19
Vývoj pro nositelná zařízení Zaměření na účel Nabídka: Kontextový stream Dotaz: Cue cards
Vytvoření emulátoru Android Wear Projekt aplikace pro Android Wear Posílání notifikace do hodinek Hospodaření s plochou displeje Aplikace na popředí
573 573 575 575
576 579 584 587 589
Kapitola 20
Novinky verze 7.0 Nougat Vylepšené notifikace Podpora více oken (Multi-Window) Jak povolit režim Freeform na zařízení nebo emulátoru s Androidem 7.0 Životní cyklus aplikace podporující Multi-Window Příklad aplikace podporující Multi-Window Režim obraz v obraze (Picture-In-Picture)
Vývoj aplikace pro Android TV Specifika televizoru z hlediska běhu aplikací Vytvoření projektu aplikace
Spuštění aplikace pro Android TV na emulátoru
K2301_blok.indd 13
595 595 601 603 604 605 608
609 609 610
613
23.5.2017 13:18:38
OBSAH
14
Kapitola 21
Publikování aplikací do aplikačního obchodu Google Play 615 Reklama v mobilních aplikacích Formáty reklamy v mobilních aplikacích Odhad profitu z reklamy v aplikacích Specifika a cílení reklamy Modely platby od inzerentů Kritéria úspěšnosti aplikace Google AdWords Zviditelněte se ve vyhledávání Google Play
Možnosti a povinnosti vývojáře vůči aplikačnímu obchodu a publikované aplikaci Registrace vývojářského účtu Vytvoření stránky vývojáře Vytvoření balíčku aplikace na publikování Pravidla publikování aplikace Publikování aplikace Snímky obrazovky Ikona ve vysokém rozlišení Hlavní grafika
616 616 617 619 619 620 621
622 622 623 624 626 628 629 630 630
Propagační grafika
630
Propagační video
631
Rejstřík
K2301_blok.indd 14
615
633
23.5.2017 13:18:38
Uživatelské rozhraní a události
K A P I T O L A
5 Témata kapitoly: Kontejnery na rozmístění prvků
Každý prvek v uživatelském rozhraní aplikace pro Android je podtřídou třídy View, přesněji android.view.View. Android SDK obsahuje sadu předpřipravených prvků, které se nejčastěji používají k tvorbě uživatelského rozhraní. Typickým příkladem jsou prvky typu TextView, Button, Checkbox, Progressbar a mnohé další. Objekty (prvky) uživatelského rozhraní se často označují i jako widgety nebo komponenty. Kromě předdefinovaných standardních prvků, které jsou součástí Android SDK, můžete vytvářet vlastní komponenty. Můžete je vytvářet jako rozšíření existujících tříd nebo vytvořit komponenty úplně nové.
Příklad – Definice rozložení prvků Příklad – Spuštění jiné aktivity Ladění aplikace
Každý prvek odvozený od třídy View zabírá v uživatelském rozhraní odpovídající obdélníkovou plochu. Prvek je zodpovědný za to, co se v tomto obdélníku zobrazuje, a také za to, aby adekvátně reagoval na události, ke kterým dochází v rámci této části obrazovky, například na dotykové události. Obrazovka uživatelského rozhraní se skládá z hierarchie prvků View. Na nejvyšší úrovni hierarchie je kořenový element a podřízené (nebo v tomto případě vnořené), prvky jsou umístěny na nižších větvích hierarchického stromu. Pohled (view) může být i kompozitní, to znamená složený z několika pohledů. Takovéto pohledy jsou podtřídy třídy Android ViewGroup (Android.view.ViewGroup) a tato třída je zase podtřídou View. Dobrým příkladem takovéhoto pohledu je RadioGroup, prvek, který vizuálně i funkčně zapouzdřuje více objektů RadioButton. Je to přesná analogie reálného světa, protože prvek RadioButton je ekvivalentem jednoho z více tlačítek, která se na starých radiopřijímačích používala k přepínání vlnových rozsahů. V poloze „zapnuto“ mohlo být vždy pouze jedno ze skupiny tlačítek. Ale vraťme se k prvkům uživatelského rozhraní aplikace pro Android. Z hlediska struktury kompozitních prvků se tyto skládají z jednoho nadřazeného pohledu odvozeného od třídy ViewGroup , který nazýváme také kontejner, nebo výstižněji
K2301_blok.indd 135
23.5.2017 13:18:55
KAPITOLA 5 UŽIVATELSKÉ ROZHRANÍ A UDÁLOSTI
136
vizuální kontejner, jelikož v sobě zapouzdřuje prvky uživatelského rozhraní, případně tyto mohou být různě hierarchicky sdružené ve vnořených kontejnerech. Pro vnořené komponenty z hlediska syntaxe XML je vizuální kontejner kořenovým elementem.
Návrh uživatelského rozhraní Základem tvorby interaktivního uživatelského rozhraní jsou pohledy, skupiny pohledů a aktivity.
Views (pohledy) jsou základní třídy pro tvorbu vizuálních prvků uživatelského rozhraní
známé i pod názvem widgety. Všechny ovládací prvky uživatelského rozhraní a třídy uspořádání jsou odvozeny od Views.
ViewGroups jsou rozšířením pohledů pro tvorbu složených prvků, které, jak vyplývá z názvu, obsahují více Views.
Activities (aktivity) jsou ekvivalentem formulářů nebo dialogových oken s ovládacími prvky, které znáte z jiných platforem. Je to nejmenší logická jednotka aplikace s uživatelským prostředím. Může obsahovat propojení na jiné aktivity.
Skupiny pohledů umožňují libovolné uspořádání hierarchie uživatelského rozhraní, takže na rozdíl od jiných platforem má vývojář při definování architektury volnou ruku. Při vytvoření projektu podle šablony Blank Activity si v souboru fragment_main.xml všimněte, že prvek
<TextView>
je umístěn uvnitř skupiny pohledů <RelativeLayout>.
Obrázek 5.1: Hierarchie objektů VievGroup
Nejčastěji se k návrhu uživatelského rozhraní využívají následující prvky:
TextView – prvek umožní zobrazení textového výpisu, například hodnoty nějaké textové
proměnné a podobně. Základním parametrem, který nastavujeme u tohoto prvku, je text.
EditText – zatímco prvek TextView slouží k jednosměrné komunikaci od aplikace k uži-
vateli, to znamená, že jen zobrazuje výpisy, EditText je jednoduché nebo víceřádkové editační okno pro zadávání textových údajů. Prvek podporuje i zarovnávání slov.
K2301_blok.indd 136
ImageView
Spinner – kompozitní prvek na výběr více položek přizpůsobený výběru na malé ploše dotykového displeje telefonu. Seznam možností je možné rozbalit a některou z nich dotykem vybrat.
Button
– prvek na zobrazení obrázku.
– standardní tlačítko aktivované dotykem.
23.5.2017 13:18:55
KONTEJNERY NA ROZMÍSTĚNÍ PRVKŮ
137
CheckBox – tento dvojstavový ovládací prvek umožňuje přepínat mezi dvěma hodnotami – pravda/nepravda (true/false). Pokud je symbol prvku zaškrtnut, nabývá hodnotu true.
RadioButton
ProgressBar – prvek, pomocí něhož aplikace indikuje uživateli probíhající činnost. Pomocí parametru android:indeterminate určujete, zda se jedná o ProgressBar konečný, který ukazuje průběh v procentech, nebo nekonečný, kde nelze určit, v jakém stadiu dokončení se prováděná akce nachází.
– ovládací prvek RadioButton sám o sobě velký smysl nemá, je potřeba použít těchto prvků několik, potom fungují jako přepínač (odtud analogie RadioButton – tlačítková sada na přepínání rozsahů rozhlasového přijímače).
Kontejnery na rozmístění prvků Jak už bylo uvedeno, k definici rozmístění prvků uživatelského rozhraní slouží takzvané vizuální kontejnery, v původní terminologii Layouts. Jsou odvozeny od třídy ViewGroup. Rozmístění prvků musí být flexibilní. Za všechny uvedeme jen dva důvody: různé rozměry obrazovek a změnu orientace zařízení. Při pootočení zařízení z režimu „na výšku“ do režimu „na šířku“, případně naopak, je zpravidla zapotřebí nejen geometrická transformace, ale i změna rozmístění prvků, aby co nejlépe využily plochu obrazovky v daném režimu.
LinearLayout Umožňuje uspořádat vnořené prvky (views) horizontálně do jednoho řádku nebo vertikálně do jednoho sloupce. Klíčové parametry pro LinearLayout jsou:
orientation
layout_gravity – takzvané těžiště vizuálního kontejneru, které definuje centrální bod zarovnání vnořených view.
Layout_weight – priorita vnořeného view v rámci layoutu. Čím vyšší hodnota, tím vyšší priorita. Pokud máte v rámci layoutu tři prvky, přičemž dva z nich mají nastavený parametr weight na 0 a třetí na hodnotu 1, dva prvky s nižší prioritou zaberou prostor daný jejich obsahem a třetí prvek s vyšší prioritou vyplní zbytek plochy layoutu.
V následujícím ilustračním příkladu je uživatelské rozhraní využívající LinearLayout s vertikální orientací sestávající ze tří tlačítek. První a třetí nemá nastavený parametr weight, což v praxi znamená, že je implicitně nastavený na hodnotu 0. Prostřední tlačítko má nastavený parametr weight na hodnotu 1, takže má vyšší prioritu a zabere na výšku zbylou plochu. Parametr gravity je nastaven střídavě na hodnoty left a right.
Uživatelské 5 rozhraní a události
– směr uspořádání vnořených prvků.
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android“ xmlns:tools=“http://schemas.android.com/tools“ android:layout_width=“match_parent“ android:layout_height=“match_parent“ android:orientation=“vertical“ tools:context=“sk.pcrevue.llacko.linearlayoutapp.MainActivity“> <Button
K2301_blok.indd 137
23.5.2017 13:18:55
138
KAPITOLA 5 UŽIVATELSKÉ ROZHRANÍ A UDÁLOSTI android:id=“@+id/button1“ android:layout_width=“wrap_content“ android:layout_height=“wrap_content“ android:layout_gravity=“left“ android:text=“Button1“ /> <Button android:id=“@+id/button2“ android:layout_width=“wrap_content“ android:layout_height=“0dp“ android:layout_gravity=“right“ android:layout_weight=“1“ android:text=“Button2“ />
<Button android:id=“@+id/button3“ android:layout_width=“wrap_content“ android:layout_height=“wrap_content“ android:layout_gravity=“left“ android:text=“Button3“ /> </LinearLayout>
Obrázek 5.2: Ilustrace fungování parametrů grafity a weight
K2301_blok.indd 138
23.5.2017 13:18:55
KONTEJNERY NA ROZMÍSTĚNÍ PRVKŮ
139
RelativeLayout Relativní layouty umožňují definování vzájemných pozičních vztahů nejen mezi jednotlivými vizuálními prvky uživatelského rozhraní (views), ale i vůči rodičovskému layoutu. Aby bylo možné definovat vzájemné vazby, musí mít každý prvek jednoznačný identifikátor – atribut ID. Příklady možností definování polohy:
layout_above
layout_alignLeft
layout_alignParentLeft
layout_centerHorizontal
layout_toLeftOf
– vůči prvku se zadaným ID – vůči prvku se zadaným ID – true/false – true/false
– vůči prvku se zadaným ID
Prvky jsou implicitně umísťovány do levého horního rohu. V ilustračním příkladu ukážeme nejprve určení polohy views vůči rodičovskému layoutu. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android“ xmlns:tools=“http://schemas.android.com/tools“ android:layout_width=“match_parent“ android:layout_height=“match_parent“ android:paddingBottom=“@dimen/activity_vertical_margin“ android:paddingLeft=“@dimen/activity_horizontal_margin“ android:paddingRight=“@dimen/activity_horizontal_margin“ android:paddingTop=“@dimen/activity_vertical_margin“ tools:context=“sk.pcrevue.llacko.relativelayoutapp.MainActivity“>
<TextView android:layout_width=“150dp“ android:layout_height=“50dp“ android:layout_centerHorizontal=“true“ android:background=“@color/red“ android:text=“layout_centerHorizontal“ />
Uživatelské 5 rozhraní a události
<TextView android:layout_width=“150dp“ android:layout_height=“50dp“ android:layout_centerInParent=“true“ android:background=“@color/green“ android:text=“layout_centerInParent“ />
<TextView android:layout_width=“250dp“ android:layout_height=“50dp“ android:layout_alignParentBottom=“true“ android:layout_centerHorizontal=“true“ android:background=“@color/yellow“ android:text=”alignParentBottom + centerHorizontal” />
K2301_blok.indd 139
23.5.2017 13:18:55
KAPITOLA 5 UŽIVATELSKÉ ROZHRANÍ A UDÁLOSTI
140
Obrázek 5.3: Relativní pozicování prvků vůči rodičovskému view a relativnímu layoutu
Pomocí atributů
android:layout_alignLeft
android:layout_alignTop
android:layout_alignRight
android:layout_alignBottom
android:layout_toLeftOf
android:layout_above
android:layout_toRightOf
android:layout_below
můžete definovat pozice prvků vůči jiným prvkům. V následujícím příkladu jsme jeden prvek ukotvili vůči rodičovskému view a druhé dva prvky jsou ukotveny relativně vůči tomuto prvku. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android“ xmlns:tools=“http://schemas.android.com/tools“ android:layout_width=“match_parent“ android:layout_height=“match_parent“ android:paddingBottom=“@dimen/activity_vertical_margin“ android:paddingLeft=“@dimen/activity_horizontal_margin“ android:paddingRight=“@dimen/activity_horizontal_margin“ android:paddingTop=“@dimen/activity_vertical_margin“ tools:context=“sk.pcrevue.llacko.relativelayoutapp.MainActivity“> <TextView android:id=“@+id/zakladny“ android:layout_width=“150dp“ android:layout_height=“50dp“
K2301_blok.indd 140
23.5.2017 13:18:55
KONTEJNERY NA ROZMÍSTĚNÍ PRVKŮ
141
android:layout_centerInParent=“true“ android:background=“@color/yellow“ android:text=“Zakladny“ <TextView android:layout_width=“150dp“ android:layout_height=“50dp“ android:layout_below=“@id/zakladny“ android:background=“@color/red“ android:text=“below“ /> <TextView android:layout_width=“90dp“ android:layout_height=“150dp“ android:layout_alignBottom=“@id/zakladny“ android:layout_toRightOf=“@id/zakladny“ android:background=“@color/green“ android:text=“toRightOf\nalignBottom“ /> </RelativeLayout>
Uživatelské 5 rozhraní a události
Obrázek 5.4: Relativní pozicování prvků vůči jiným prvkům
Relativní layouty jsou velmi flexibilní, ale pouze v případě, že definujete mezi prvky jen minimální počet vazeb. V opačném případě se stává návrh nepřehledným a vzniknou takzvané kruhové vazby a rozpory, například mezi definováním rozměrů prvků a okrajů vzhledem k rozměru rodičovského layoutu, který zabírá celou šířku obrazovky. Pokud se třeba součet šířky prvku a jeho levého a pravého okraje nerovná šířce rodičovského kontejneru, nastane problém.
K2301_blok.indd 141
23.5.2017 13:18:55
KAPITOLA 5 UŽIVATELSKÉ ROZHRANÍ A UDÁLOSTI
142
FrameLayout Tento layout umožňuje zobrazit jen jeden prvek (view). Využívá se hlavně k zobrazování dynamicky vytvářených fragmentů pro verze operačního systému starší než 3.0 a komplexnějších prvků, například ScrollView. Pokud byste do FrameLayoutu vložili více prvků, zobrazí se na tom samém místě, přičemž budou zarovnané podle levého horního rohu. Umístění prvků je možné ovlivňovat pomocí atributu android:layout_gravity. Obrázek 5.5: Příklad rozmístění prvků s využitím kontejneru FrameLayout
<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”sk.pcrevue.llacko.framelayoutapp.MainActivity”> <View android:layout_width=”150dp” android:layout_height=”150dp” android:background=”@color/red” /> <View android:layout_width=”200dp” android:layout_height=”200dp” android:layout_gravity=”bottom|right” android:background=”@color/green” /> <TextView android:id=”@+id/textView” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_gravity=”center”
K2301_blok.indd 142
23.5.2017 13:18:55
KONTEJNERY NA ROZMÍSTĚNÍ PRVKŮ
143
android:text=”@string/hello_world” /> </FrameLayout>
TableLayout Do verze API 14 (Android 4.0) se na organizování prvků uživatelského rozhraní do formy tabulek, tedy řádků a sloupců, využíval TableLayout. Ke konstrukci řádků tabulky se využívá kontejner TableRow. Při vytváření složitějších tabulek oceníte možnost roztáhnout pole přes několik buněk tabulky. Od verze 4.0 se mnohem více využívá intuitivní kontejner GridLayout. V příkladu je tabulka denních maximálních a minimálních teplot. Kvůli zkrácení výpisu jsou odstraněné identifikátory jednotlivých buněk tabulky, text je vložen přímo, a nikoliv pomocí zdrojů jako v reálných aplikacích a pro každý řádek je uvedena jen jedna hodnota. <TableLayout xmlns:android=“http://schemas.android.com/apk/res/android“ xmlns:tools=“http://schemas.android.com/tools“ android:layout_width=“match_parent“ android:layout_height=“match_parent“ android:collapseColumns=““ android:shrinkColumns=“*“ android:stretchColumns=“*“ tools:context=“sk.pcrevue.llacko.tablelayoutapp.MainActivity“>
<TextView android:id=“@+id/textViewNadpis“ android:layout_width=“match_parent“ android:layout_height=“wrap_content“ android:gravity=“center“ android:padding=“8dp“ android:text=“Denné maximá a minimá teplôt“ android:textSize=“13dp“ android:textStyle=“bold“> </TextView> </TableRow>
Uživatelské 5 rozhraní a události
<TableRow android:id=“@+id/tableRowNadpis“ android:layout_width=“match_parent“ android:layout_height=“wrap_content“ android:gravity=“center_horizontal“ >
<TableRow android:layout_width=“match_parent“ android:layout_height=“wrap_content“ > <TextView android:text=““ > </TextView> <TextView android:gravity=“center“
K2301_blok.indd 143
23.5.2017 13:18:55
144
KAPITOLA 5 UŽIVATELSKÉ ROZHRANÍ A UDÁLOSTI android:text=“1.5“> </TextView> ... </TableRow> <TableRow android:id=“@+id/tableRowHttp“ android:layout_width=“match_parent“ android:layout_height=“wrap_content“ > <TextView android:id=“@+id/textView10“ android:text=“MIN“ android:textStyle=“bold“ > </TextView> <TextView android:id=“@+id/textView11“ android:gravity=“center_horizontal“ android:text=“12“ > </TextView> ... </TableRow> <TableRow android:id=“@+id/tableRowHttps“ android:layout_width=“match_parent“ android:layout_height=“wrap_content“ > <TextView android:id=“@+id/textView20“ android:text=“MAX“ android:textStyle=“bold“ > </TextView> <TextView android:id=“@+id/textView21“ android:gravity=“center_horizontal“ android:text=“26“ > </TextView> ... </TableRow> </TableLayout >
K2301_blok.indd 144
23.5.2017 13:18:55