Programování pro operační systém Android. Ilustrační foto | foto: Mobil

Programování pro operační systém Android. Ilustrační foto | foto: Mobil | foto: Michal Havryluk, Mobil.iDNES.cz

Nadšenci do Androidu, chcete se naučit programovat? Pokračujeme v kurzu

  • 5
Naše minulá aplikace byla menším kvízem, na kterém jsme předvedli základní principy programování pro nejrozšířenější mobilní operační systém současnosti. Dnes budeme pokračovat a přidáme seznam s výsledky účastníků našeho kvízu.

Než se pustíte do čtení tohoto dílu kurzu, doporučujeme projít nejprve první díl (o začátcích programování se dočtete v dřívějším článku Naučíme vás programovat aplikace pro Android. Začínáme), v němž jsme probírali instalace potřebných nástrojů a první krůčky na platformě Android. V dnešní části budeme na těchto základech stavět a bez nich byste se mohli velice snadno ztratit. K původnímu kvízu nyní přidáme výsledkovou tabulku účastníků. Součástí bude i uložení vašeho nejlepšího skóre do vnitřní paměti zařízení.

Ukládání do sdíleného nastavení

Předtím, než se vůbec pustíme do zobrazování statistik, potřebujeme nejprve uložit skóre po skončení kvízu. Na platformě Android existuje několik způsobů pro uložení dat. Kromě zápisu do běžného souboru můžeme využít služeb SQLite databáze nebo klidně výsledky ukládat na vzdálený server. Toto jsou však poměrně složité způsoby, které prozatím přeskočíme.

Oficiální příručka

Tento článek není v žádném případě náhradou za oficiální materiály z Android Developers Guide. Je spíše malým okénkem do světa programování pro operační systém Android. Zdrojový kód rovněž nemá ideální podobu a byl velmi zjednodušen pro potřeby tohoto článku.

Nejjednodušší je využít schopností SharedPreferences (v překladu sdílené nastavení), které slouží většinou pro ukládání nastavení ve formě jednoduchých datových položek. Ty jsou uloženy do xml souboru do prostoru vymezeného pro vaši aplikaci. Pokud neurčíte jinak, tak jsou dostupné výhradně pro vaši aplikaci. Toto určuje parametr mode při přístupu k danému sdílenému nastavení.

V našem případě si vytvoříme právě takový soubor a po skončení kvízu do něj uložíme nejvyšší skóre. Vše prozatím provádíme v rámci třídy QuizActivity a metody showStatistics. Nezapomeňte vždy po skončení práce s editorem SharedPreferences použít příkaz commit, jinak se zapsané hodnoty neuloží. Následujícím krokem je přidání dalšího tlačítka na úvodní obrazovku u třídy MainActivity. To bude směřovat na nově vytvořenou třídu ScoreActivity, kde už nás čeká vytváření seznamu výsledků.

Jeden View vládne všem

Jak už víme z minula, třída View zastřešuje všechny prvky, které můžeme umístit do layoutu od textového pole (TextView) až třeba po tlačítka (Button). Nejrozšířenějším View na Androidu je s přehledem ListView, který slouží k zobrazení seznamu libovolných položek, což jsou zase další View. V našem případě využijeme ListView pro zobrazení řádků, v nichž bude jméno účastníka kvízu a jeho skóre. Tyto údaje jsou pokaždé vytvořeny při otevření ScoreActivity a hodnoty zapsané přímo v aplikaci. V ideálním případě by se stahovaly ze serveru, kam by se výsledky zapisovaly z jednotlivých zařízení.

Náš ListView je v layoutu umístěn v tzv. RelativeLayoutu v souboru score.xml. Tento RelativeLayout umožňuje umisťovat View v něm obsažené relativně podle pozice okolních View. Typicky tedy budete nastavovat, že jeden View je napravo od druhého nebo se má ukotvit na spodní okraj svého rodiče. Různých kombinací je bezpočet. Pokud View nemá žádné údaje o tom, jak se má pozicovat, je umístěn do levého horního rohu. Dobré je vědět, že View se mohou vzájemně překrývat.

Programování pro operační systém Android

V našem případě jsme použili RelativeLayout k tomu, abychom jednak umístili nejvyšší skóre aktuálního účastníka kvízu nad celý seznam a také tlačítko pro vymazání řádku ze skóre, které bude vždy v dolním okraji obrazovky. Jak si můžete v aplikaci všimnout, není to příliš šikovná kombinace a poslední řádky ListView nejsou vidět. V rámci kódu ještě přidáme tzv. header, což bude hlavička seznamu umístěná jako první řádek. Hodí se rovněž upozornit, že se nikdy nesmí umisťovat ListView do ScrollView.

Chybějící spojka

K dispozici již tedy máme ArrayList se seznamem účastníků a ListView, do kterého budou tyto položky v podobě View řádků umístěny. Chybí nám pouze spojka, která tyto dva světy propojí. Tím je v Androidu tzv. adaptér, který se kromě ListView používá i pro jiné účely. Prakticky vždy však dělá to, že vezme hodnoty položky z ArrayListu, vytvoří k nim odpovídající View a ten umístí do ListView.

Náš adaptér má název ScoreArrayAdapter a při jeho vytváření jsme museli implementovat několik povinných metod, které jsou nutné pro funkci celého ListView. Byly to metody většinou pro získání položky na dané pozici nebo celkového množství položek v seznamu. Implementace těchto metod není žádná věda, ale zkrátka je musíme napojit na náš ArrayList.

Tou nejdůležitější metodou v adaptéru je getView, která se stará o vytvoření a úpravu položek. V rámci platformy Android je totiž vždy vytvořeno pouze tolik View řádků, kolik je jich aktuálně na displeji. Váš seznam tak může mít klidně tisíce a tisíce řádků, ale daných View pro potřeby ListView je vždy vytvořeno například deset. Použité View jsou v drtivé většině případů totožné a mění se pouze jejich obsah. Touto metodou se výrazně šetří paměť a celková náročnost na vytvoření tisíce položek. Celý popis práce adaptéru berte spíše s rezervou a princip je ještě o něco složitější.

Recyklace klíčem k úspěchu

Při vytvoření ListView je tak vytvořeno pouze například zmiňovaných deset řádků, které se při pohybu recyklují. Pokud tedy uživatel zobrazí jedenáctou pozici v seznamu, tak první řádek je ze seznamu odebrán a okamžitě se přemístí na zmíněnou jedenáctou pozici.

Adaptér se však postará o aktualizaci jeho hodnot, aby skutečně odpovídaly této pozici v seznamu. Bez toho by v ní zůstaly údaje z prvního řádku. V metodě getView se tento recyklovaný řádek dostává v podobě tzv. convertView, který se následně upravuje.

Programování pro operační systém Android

V naší metodě getView tudíž nejprve zkontrolujeme, jestli je convertView prázdný (null), což by znamenalo, že je potřeba položku nejprve vytvořit. K tomuto účelu je použit tzv. LayoutInflater, který je schopný vzít xml soubor s layoutem a vytvořit z něj potřebný View. Tento soubor máme již připravený ve složce layouts. Třídy LayoutInflater jsme využili i pro vytvoření hlavičky ListView v předchozí sekci.

Pokud nebyl convertView prázdný nebo jsme ho právě vytvořili, je potřeba ještě nastavit údaje u TextView, aby odpovídaly pozici, kde se má tento View zobrazit. V našem případě to znamená získat objekt na této pozici v ArrayListu a následně odpovídající jméno účastníka a jeho skóre.

Perličkou na závěr je obarvení pozadí každého druhého řádku tmavší barvou, aby se údaje lépe četly. Toho dosáhneme provoláním metody setBackgroundColor na daný View řádek. Avšak pozor, musí existovat také druhá varianta, která nastaví průhledné pozadí řádku. Pokud by tato varianta neexistovala, dočkali bychom se nemilého překvapení při pohybu v ListView.

Mazání konkurence

V ScoreActivity je umístěno ještě jedno tlačítko pro vymazání první pozice seznamu výsledků. Po jeho stisknutí je provolána metoda deleteItem u našeho adaptéru, kdy je položka odstraněna z ArrayListu. Velice podstatné je provolání metody notifyDataSetChanged, kdy informujeme adaptér, že došlo ke změně dat a je nutné ho překreslit. Pokud bychom to neudělali, nic by se na první pohled nestalo.

Programování pro operační systém Android

ListView může být kromě hodnot z ArrayListu plněn i hodnotami z tzv. Cursoru přímo z databáze, což je ještě efektivnější postup pro plnění ListView. I v jeho rámci je potřeba zavolat, že došlo ke změně datové základny a je potřeba ListView znovu překreslit.

Úkoly pro vás

Stejně jako minule jsou k dispozici dva Eclipse projekty. Oba jsou náležitě okomentovány a mělo by z nich být jasné, jak se s aplikací pracuje. První projekt obsahuje kompletní zdrojové kódy aplikace. Druhý projekt má odmazané některé části kódu, konkrétně uložení nejlepšího výsledku po skončení celého kvízu. Pro tento účel se používá tzv. Editor, který získáte z daného SharedPrefences provoláním metody edit. Vodítko, jak pracovat se SharedPreferences, je ukázáno hned v úvodu ScoreActivity.

Druhým úkolem je přidání obarvování každého druhého řádku v seznamu tmavší barvou. K tomu použijete metodu setBackgroundColor, která bude mít jako svůj parametr zvolenou barvu. Tu si můžete vytvořit samozřejmě vlastní, ale v rámci zjednodušení doporučujeme použít barvy standardně obsažené u každého androidího zařízení. Jsou jimi například barvy android.R.color.darker_gray a android.R.color.transparent. Pro jejich získání provolejte metody context.getResources().getColor().

Na závěr pro jistotu ještě upozornění. Máte-li ještě uložený původní projekt z předchozího článku, tak ho v Eclipse vymažte a importujte jeden z výše uvedených projektů.