Let's start!
Ciele
  1. Naučiť sa prenášať dáta medzi aktivitami.
  2. Použiť dialóg.
  3. Vytvoriť si vlastný návrhový view objekt.
  4. Naučiť sa vykresľovať jednoduché grafické prvky.
Úvod
Na minulých cvičeniach ste si osvojili základnú štruktúru Android aplikácií a naučili ste sa pracovať s rôznymi zdrojmi. V tomto cvičení pripravíte základňu pre samotné hranie vyvíjanej puzzle hry.
Postup
  1. V tomto kroku pripravíte základ pre hranie hry - vytvorenie si vlastného návrhového view prvku, ktorý bude predstavovať hraciu plochu, vytvorenie prislúchajúcej obsluhujúcej Aktivity
    Úloha:  Otvorte si projekt HelloAndroid z minulého cvičenia alebo si ho stiahnite a importujte do vývojového prostredia Eclipse.
    Úloha:  Vytvorte návrhový XML súbor pre novú hru game.xml cez kontextové menu New -> Other -> Android XML File, ako typ zdroja uveďte Layout a koreňový element nech je LinearLayout.
    Úloha:  Vytvorte v adresári /src/tuke.fei.hello triedu GameView.java, ktorá rozširuje triedu View.
    Úloha:  Pridajte v tejto triede dva konštruktory
              public GameView(Context context, AttributeSet attrs) {
                super(context, attrs);
              }
              
              public GameView(Context context) {
                super(context);
              }
            
    Poznámka:  Nový prispôsobený view, trieda GameView bude obsluhovať samotnú hru, t.j. obrazovku a interakciu s používateľom.
    Úloha:  Pridajte v návrhovom súbore game.xml vnútri elementu LinearLayout vlastný view element tuke.fei.hello.GameView s atribútmi:
              android:id="@+id/tile_view"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
            
    Úloha:  Vytvorte v adresári /src/tuke.fei.hello prislúchajúcu Aktivitu Game.java.
    Poznámka:  Nezabudnite pridať novú Aktivitu do manifestu AndroidManifest.xml
    Úloha:  Implementujte metódu onCreate() nasledovne:
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.game);
              }
            
    Úloha:  Pridajte v zdrojovom súbore strings.xml reťazec "New" predstavujúci text na tlačidle pre novú hru.
    Úloha:  Pridajte v zdrojových návrhových XML súboroch pre úvodnú obrazovku /res/layout/main.xml a /res/layout-land/main.xml tlačidlo pre vytvorenie novej hry s identifkátorom mbutton_new a textom na tlačidle referujúcim na predchádzajúci definovaný zdrojový reťazec.
    Uvažujeme stav, keď používateľ stlačí tlačidlo pre novú hru, najprv sa zobrazí dialóg s výberom obtiažnosti hry a po potvrdení môže začať hrať hru.
    Úloha:  Pridajte v zdrojovom súbore /res/values/strings.xml reťazec "Difficulty" pod menom new_game_dif, ktorý bude zobrazovaný v úvodnom dialógu .
  2. V tomto kroku sa naučíte používať dialóg typu AlertDialog.
    AlertDialog je najpoužívanejší a odporúčaný prvok pri konštrukcii používateľských rozhraní. Tento typ dialógu môže obsahovať
    • názov
    • text
    • 0, 1, 2 alebo 3 tlačidlá (k dispozícii sú 3 typy tlačidiel, pozitívne, negatívne a neutrálne, pričom každý typ sa môže použiť v dialógu iba raz) a/alebo
    • zoznam voliteľných položiek (checkboxy-y, radio button-y)
    Úloha:  Vytvorte v triede /src/tuke.fei.hello/Hello.java privátnu metódu bez návratovej hodnoty startGame(int), ktorá bude akciou na výber obtiažnosti v úvodnom dialógu hry, teda jej parametrom bude zvolený stupeň obtiažnosti.
    Úloha:  Implementujte metódu tak, aby spustila Aktivitu Game.
    Úloha:  Vytvorte v triede /src/tuke.fei.hello/Hello.java privátnu metódu bez návratovej hodnoty openNewGameDialog().
    Na vytvorenie dialógu je potrebné použiť podtriedu AlertDialog.Builder. Inštanciu Builder objektu získate pomocou konštruktora AlertDialog.Builder(Context) a využitím jeho verejných metód sa definujú vlastnosti dialógu.
    Úloha:  Vytvorte v metóde openNewGameDialog() objekt typu Builder.
    Úloha:  Pre nastavenie názvu dialógu zavolajte na danom objekte verejnú metódu setTitle(CharSequence), ktorej parametrom bude referencia na zdrojový reťazec pre názov dialógu pridaný v predchádzajúcom kroku.
    Úloha:  Pre pridanie zoznamu voliteľných položiek zavolajte na danom objekte verejnú metódu setItems(), ktorej
    • prvým parametrom bude referencia na zdrojové pole vytvorené v predchádzajúcom cvičení, ktoré tvoria stupne obtiažnosti,
    • druhým parametrom bude nový objekt typu DialogInterface.OnClickListener, ktorý definuje akciu na výber položky zo zoznamu:
                new DialogInterface.OnClickListener() {
                			public void onClick(DialogInterface dialoginterface, int i) {
                					// akcia na vyber stupna obtiaznosti
                					startGame(i);
                			}
             		  })
              
    Poznámka:  Druhý parameter metódy onClick() definuje poradie zvoleného prvku v zozname, začínajúc v zozname od 0.
    Úloha:  Vyvolajte zobrazenie dialógu zavolaním metódy show() na objekte typu Builder.
    Úloha:  Upravte v triede /src/tuke.fei.hello/Hello.java metódu onClick() tak, aby reagovala na tlačidlo New zavolajúc metódu openNewGameDialog().
    Poznámka:  Nezabudnite pridať handler pre kliknutie na dané tlačidlo v metóde onCreate().
  3. V tomto kroku sa naučíte posielať dáta medzi aktivitami využijúc objekt typu Intent, s ktorým ste sa oboznámili na prvom cvičení.
    Intent poskytuje sekundárne atribúty, akými sú napr.
    • kategória vyvolanej akcie
    • typ dát objektu typu Intent
    • možnosť pripojenia doplnkových informácií
    Práve možnosť pripojenia doplkových informácií umožňuje posielanie rôznych typov dát medzi aktivitami vo forme kľúč-hodnota.
    Úloha:  Vytvorte v Aktivite /src/tuke.fei.hello/Game.java verejnú statickú premennú typu String KEY_DIFFICULTY a priraďte jej jedinečný reťazec, ktorý poslúži ako identifikažný kľúč.
    Úloha:  Upravte metódu startGame() v triede /src/tuke.fei.hello/Hello.java tak, aby pred vyvolaním Aktivity Game objekt typu Intent uložil pod kľúčom Game.KEY_DIFFICULTY zvolenú položku (poradie) v dialógu pomocou volania metódy putExtra(String, int).
    Úloha:  Upravte metódu onCreate() v Aktivite /src/tuke.fei.hello/Game.java tak, že do lokálnej premennej typu int priradíte prenášanú hodnotu.
    Objekt typu Intent získate volaním metódy getIntent(), pre výber doplnkovej hodnoty je potrebné zavolať na tomto objekte metódu get[typ]Extra(String, int), kde typ zodpovedá typu uloženej hodnoty a druhý parameter zodpovedá prednastavenej hodnote, ktorá je vrátená, ak danému kľúču nie je priradená žiadna hodnota.
    Poznámka:  Pre posielanie zložitejších objektov bude lepšie použiť triedy implementujúce rozhranie Parcelable, ktorých inštancie môžu byť zapísané a získané z triedy Parcel (úložisko pre dátové a objektové referencie posielané prostredníctvom IBinder). Takýto spôsob využijeme v ďalších cvičeniach.
  4. V tomto kroku zavediete funkcionalitu pre svoj vytvorený view prvok - vypíše zvolený počet dlaždíc.
    Úloha:  Deklarujte vo View /src/tuke.fei.hello/GameView.java privátne premenné myDifficulty a myTileCount typu int.
    Úloha:  Ďalej deklarujte privátnu premennú myPaint typu Paint.
    Úloha:  Vytvorte verejnú metódu newGame(int) vo View /src/tuke.fei.hello/GameView.java bez návratovej hodnoty, kde parametrom bude zvolená obtiažnosť hry, teda počet dlaždíc na riadok aj stĺpec.
    Úloha:  Priraďte v nej premennej myDifficulty hodnotu parametra a premennej myTileCount hodnotu rovnú počtu dlaždíc v celom hracom poli.
    Úloha:  Vytvorte privátnu metódu init() bez návratovej hodnoty, ktorej telo bude pozostávať z vytvorenia objektu typu Paint a priradenia tohto objektu do premennej myPaint.
    Rámec v závislosti od používateľovho vstupu zachytí bežnú zmenu fokusu, čo zahŕňa zmenu fokusu keď je View zničený, skrytý alebo sa stane aktívny iný View objekt.
    Úloha:  Pridajte do danej metódy nasledujúce riadky upravujúce možnosti prevzatia fokusu daného View objektu
              setFocusable(true);
              setFocusableInTouchMode(true);
              
    Úloha:  Aktualizujte konštruktory danej triedy o volanie metódy init().
    Aby ste mohli vykresľovať prvky v danom View, potrebujete implementovať metódu onDraw(Canvas theCanvas), ktorá sa volá vždy, keď sa obsah View objektu zmení. Parametrom tejto metódy je objekt typu Canvas, na ktorý bude vykreslené pozadie.
    Úloha:  Pridajte do zdrojového súboru /res/values/colors.xml farbu vykresľovaného textu puzzle_number, napr. #ffBBDDBB.
    Úloha:  Implementujte metódu onDraw(Canvas) tak, že upravíte niektoré vlastnosti maľovanej plochy (farba a veľkosť textu, spôsob vykresľovania) a na plátne (objekte typu Canvas získanom ako parameter) zavoláte metódu drawText():
              @Override
              protected void onDraw(Canvas theCanvas) {
                // nastavenie farby textu
                myPaint.setColor(getResources().getColor(tuke.fei.hello.R.color.puzzle_number));
                // nastavenie velkosti textu
                myPaint.setTextSize(20);
                // pozicia vykreslovania textu vzhladom na urceny bod
                myPaint.setTextAlign(Paint.Align.CENTER);
                // vykreslenie textu
                theCanvas.drawText(String.valueOf(myDifficultyCount), getWidth()/2, getHeight()/2, myPaint);
              }
              
    Poznámka:  Pre určenie základných farieb môžete využívať aj triedu android.graphics.Color.
    Poznámka:  Metódy getWidth() a getHeight() definujú aktuálnu šírku a výšku View objektu na obrazovke v čase vykresľovania.
    Úloha:  Upravte metódu onCreate() v Aktivite /src/tuke.fei.hello/Game.java tak, že získate objekt typu GameView na základe jeho uloženého identifikátora definovaného v návrhovom súbore /res/layout/game.xml pomocu metódy findViewById(int).
    Úloha:  Zavolajte na danom objekte metódu requestFocus().
    Úloha:  Do lokálnej premennej ste pred niekoľkými krokmi uložili hráčovu voľbu obtiažnosti. Tento údaj predstavuje poradie opložky v zozname - vytvorte teda funkciu privátnu metódu getCount(int) s návratovou hodnotou typu int, ktorá vráti počet dlaždíc na riadok a stĺpec v závislosti od tejto voľby.
    Teda:
    • 0 vráti 4
    • 1 vráti 5
    • 2 vráti 8
    Úloha:  Zavolajte na objekte typu GameView metódu newGame(), ako parameter využite hodnotu vrátenú funkciou getCount().
Doplňujúce úlohy