AND THE WINNER IS...
Ciele
- Naučiť sa pracovať s SQLite databázou v Androide.
- Pridanie, zobrazenie a uloženie najlepších časov.
Úvod
Android obsahuje balíky s triedami na prácu s dátami obsiahnutými v content provider-y.
Tieto triedy umožňujú aj prácu s privátnou SQLite databázou. Tú využijete
pre interné ukladanie nahraných časov v hre.
Postup
-
Už v aplikácii máte implementovaný časovač, ktorý počíta V tomto kroku sa naučíte ako vytvoriť a pracovať s internou databázou, do ktorej neskôr budete ukladať nahrané skóre.Úloha: Vytvorte triedu src/tuke.fei.hello/ScoreItem.java ktorej objekty budú reprezentovať záznamy v databáze, pozostávajúce z mena hráča (String) a nahraného skóre (Integer) a ich zapúzdrenia.Na prácu s databázou je určený balík android.database.Úloha: Vytvorte podtriedu src/tuke.fei.hello/ScoreDatabase.java triedy SQLiteOpenHelper, ktorá slúži na manažment databázy. Vaša trieda tak bude mimo iných implementovať metódy onCreate() pre vytvorenie databázy ak neexistuje a onUpgrade() pre upgrade ak je nevyhnutný.Cieľom využitia tejto databázy je ukladanie hráčových skóre z hry, teda bude stačiť vytvoriť jednu tabuľku, v ktorej budú uložené záznamy obsahujúce jedinečné ID záznamu, meno hráča (TEXT), dosiahnuté skóre (INTEGER) a príznak (INTEGER), ktorý využijete v neskorších cvičeniach, udávajúci, či bolo dané skóre odoslané prostredníctvom web-servisu.Úloha: Deklarujte a inicializujte 5 jedinečných statických reťazcov pre meno databázy DB_NAME, meno tabuľky SCORETABLE, mená stĺpcov COL_NAME, COL_SCORE, COL_SENT.Úloha: Pridajte jednoduchý konštruktor vytvárajúci pomocný objekt na prácu s databázou, objekt v parametroch typu CursorFactory slúžiaci na tvorbu kurzorov môžete ponechať null, číslo verzie je voliteľné.
public ScoreDatabase(Context theContext) { super(theContext, DB_NAME, null, 1); }
Úloha: Implementujte metódu onCreate(SQLiteDatabase), ktorá je volaná keď je vytváraná nová databáza. Tu teda vytvoríte tabuľku so zvolenými stĺpcami volaním metódy execSQL(String) na objekte databázy, ktorej parametrom je štandardný SQL príkaz pre vytvorenie tabuľky.Poznámka: V dotazoch môžete využiť statické reťazce riedy BaseColumns, napr. pre názov stĺpca identifikátorov BaseColumns._ID.Implementácia metódy onUpgrade(SQLiteDatabase, int, int), ktorá je volaná, ak je potrebná zmena na danej databáze, je voliteľná. V tejto metóde je možné mazanie, pridávanie tabuliek ai.Úloha: Vytvorte a implementujte verejné metódy- getAllOrdered() - vráti objekt typu Cursor ukazujúci na všetky záznamy zoradené zostupne podľa hodnoty skóre
- getAllFormated() - načíta a vráti zoradené záznamy do listu objektov typu ScoreItem
- add(final String, final int) - pridá nový záznam do tabuľky
- remove(final int) - vymaže záznam pod daným ID
- removeAll() - vymaže všetky záznamy
Poznámka: Objekt databázy v metódach získate volaním metódy getWritableDatabase().Poznámka: Dotaz na objekte databázy vytvoríte volaním metódy query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy).Poznámka: Na vykonanie zmien v tabuľke využite metódy insert(String table, String nullColumnHack, ContentValues values), delete(String table, String whereClause, String[] whereArgs), update(String table, ContentValues values, String whereClause, String[] whereArgs)Neskôr si v stave spusteného AVD záznamy v databáze môžete prechádzať v okne Window -> Open Perspective -> Other -> DDMS v záložke FileExplorer -> data -> data -> tuke.fei.hello -> databases alebo cez ľubovoľný externý prehliadač z exportovaného databázového súboru (možnosť vrpavo hore Pull a file from the device) -
Databázu máte pripravenú, v tomto kroku teda ostáva vytvoriť funkcionalitu pre zápis nového skóre po vyriešení hry.Predpokladáme, že po vyriešení hry, teda presunom poslednej dlaždice na správne miesto sa zobrazí ponuka uloženia zahraného skóre (času v sekundách) s možnosťou zadania mena hráča. Okno ponuky bude obsahovať animovaný obrázok, textové pole pre zobrazenie skóre, editovateľné textové pole pre zadanie mena a tlačidlo pre odoslanie.Úloha: Upravte Aktivitu src/tuke.fei.hello/Game.java, obdobne ako ste posielali zvolený stupeň obtiažnosti medzi aktivitami, deklarujte statickú premennú KEY_SCORE a priraďte jej jedinečný reťazec, ktorý bude slúžiť ako kľúč pre prenos hodnoty skóre medzi Aktivitou pre hru a Aktivitou pre uloženie skóre.Úloha: Vytvorte verejnú metódu callScore() bez návratovej hodnoty.Úloha: Implementujte zastavenie chronometra, odpočítanie uplynutého času a prevedenie tohto času na sekundy.Úloha: Aplikujte volanie metódy callScore() v triede src/tuke.fei.hello/GameView.java v prípade, že hráč úspešne vyriešil hru.Úloha: Vytvorte návrhový súbor pre okno s ponukou uloženia skóre /res/layout/new_score.xml , ako koreňový element zadajte LinearLayout s vertikálnou orientáciou obsahu vypĺňajúci celú obrazovku.Úloha: Doplňte elementy pre prvky tvoriace obsah okna s ponukou, priraďte každému jedinečný identifikátor a atribúty podľa nasledujúcich požiadaviek
-
ImageView a TextView svoje rozmery
prispôsobujú obsahu a sú horizontálne vycentrované pomocou atribútu
android:layout_gravity="center_horizontal"
-
EditText sa prispôsobuje šírke obrazovky, výška
závisí od obsahu a je editovateľný pridaním atribútu
android:editable="true"
- Button sa prispôsobuje šírke obrazovky, výška závisí od obsahu
Úloha: Vytvorte príslušnú Aktivitu src/tuke.fei.hello/NewScore.java implementujúcu OnClickListener, keďže budete vytvárať akciu na stlačenie tlačidla a implementujte základ metódy onCreate(Bundle)@Override public void onCreate(Bundle theSavedInstanceState) { super.onCreate(theSavedInstanceState); setContentView(R.layout.new_score); }
Poznámka: Nezabúdajte pridať každú novú Aktivitu do manifestu aplikácie. Pre krajší vzhľad môžete pridať tejto Aktivite rovnakú tému ako má Aktivita About.Úloha: Vyvolajte túto Aktivitu v triede src/tuke.fei.hello/Game.java v metóde callScore(), pridajte dáta pre prenos pod kľúčom KEY_SCORE.Úloha: Uložte si do zdrojového adresára /res/drawable obrázok zobrazovaný v okne pre zápis skóre, na ktorý sa bude aplikovať animácia.Úloha: Upravte metódu onCreate() Aktivity NewScore tak, aby v nej bol načítaný obrázok do objektu typu Bitmap pomocou BitmapFactory.decodeResource(Resources, int) ako v prípade načítania puzzle obrázok.Úloha: Na objekte typu ImageView definovanom v príslušnom vyššie vytvorenom návrhovom súbore nastavte zobrazovaný obrázok pomocou volania setImageDrawable(BitmapDrawable), kde parametrom je objekt vytvorený z načítanej bitmapy, a aplikujte animáciu rotation, alpha alebo scale.Úloha: Zobrazte skóre uložené v extra dátach prenášaných medzi aktivitami volaním metódy setText(String) na objekte typu TextView definovanom v príslušnom vyššie vytvorenom návrhovom súbore.Úloha: Nastavte obsluhu udalosti pre stlačenie tlačidla na uloženie skóre.Úloha: Upravte metódu onClick(View), načítajte meno hráča z objektu editovateľného textového poľa volaním metódy getText() .Úloha: Vytvorte objekt pre prácu s databázou typu ScoreDatabase a zavolajte na ňom metódu pre uloženie záznamu.Úloha: Korektne ukončite prácu s databázou a Aktivitu. -
ImageView a TextView svoje rozmery
prispôsobujú obsahu a sú horizontálne vycentrované pomocou atribútu
-
Cieľom tohto kroku je pridať do možností hry prezeranie si doposiaľ nahraných skóre.Úloha: Pridajte ďalšie tlačidlo do úvodného menu hry pre prezeranie si najlepších dosiahnutých hracích časov.Úloha: Vytvorte návrhový súbor pre zobrazenie najlepších skóre /res/layout/scores.xml , ako koreňový element zadajte LinearLayout s vertikálnou orientáciou obsahu vypĺňajúci celú obrazovku.Predpokladáme, že sa zobrazí tabuľka skóre doplnená tlačidlom pre možnosť vymazania všetkých doposiaľ uložených záznamov.Úloha: Doplňte elementy pre prvky tvoriace obsah okna s ponukou, priraďte každému jedinečný identifikátor a atribúty podľa nasledujúcich požiadaviek
-
TableLayout svoje rozmery
prispôsobuje obsahu a indexovo založeným atribútom android:stretchColumns
udáva maximálne roztiahnutie prvého stĺpca.
android:padding="30dip" android:stretchColumns="0"
- Button sa prispôsobuje šírke obrazovky, výška závisí od obsahu
Úloha: Vytvorte príslušnú Aktivitu src/tuke.fei.hello/Scores.java implementujúcu OnClickListener, keďže budete vytvárať akciu na stlačenie tlačidla a implementujte základ metódy onCreate(Bundle)@Override public void onCreate(Bundle theSavedInstanceState) { super.onCreate(theSavedInstanceState); setContentView(R.layout.scores); }
Poznámka: Nezabúdajte pridať každú novú Aktivitu do manifestu aplikácie. Pre krajší vzhľad môžete pridať tejto Aktivite rovnakú tému ako má Aktivita About.Úloha: Vytvorte privátnu metódu loadData(), ktorá bude napĺňať zobrazovanú tabuľku jednotlivými údajmi.Princíp plnenia tabuľkového objektu údajmi znamená, že budete do daného objektu pridávať ďalšie view objekty v podobe riadku typu TableRow tvoreného textovými poľami typu TextView. Na začiatku metódy je preto dobré všetky existujúce view, ktoré tabuľka obsahuje vymazať pomocou volania metódy removeAllViews().Úloha: Vytvorte objekt tabuľky definovaný v návrhovom súbore elementom TableLayout a vykonajte na ňom potrebné operácie.Úloha: Načítajte si v danej metóde uložené skóre , teda sformátované dáta v podobe zoznamu objektov typu ScoreItem a pre každý prvok zoznamu vytvorte objekt typu TableRow.Úloha: Pre meno a skóre hráča obsiahnuté v každom prvku vytvorte jednotlivo objekty typu TextView, prideľte im príslušný text a pridajte ich riadka pomocou volania metódy na objekte riadka tabuľky addView(View) .Úloha: Pridajte riadok pomocou volania tej istej metódy do objektu tabuľky.Úloha: Načítajte dáta pri vytváraní Aktivity.Úloha: Nastavte obsluhu udalosti stlačenia tlačidla pre vymazanie doteraz uložených skóre pri vytváraní Aktivity.Úloha: Implementujte akciu na stlačenie tlačidla zmazaním údajov v databáze a následným obnovením obsahu zobrazovanej tabuľky.Úloha: Implementujte v Aktivite src/tuke.fei.hello/Hello.java akciu na stlačenie tlačidla pre zobrazenie najlepších odohraných časov, teda vyvolanie Aktivity Scores. -
TableLayout svoje rozmery
prispôsobuje obsahu a indexovo založeným atribútom android:stretchColumns
udáva maximálne roztiahnutie prvého stĺpca.
Doplňujúce úlohy
- Upravte uloženie a zobrazenie odohraného času s ohľadom na zvolenú obtiažnosť hry.
Ďalšie zdroje