2 Boter Kaas & Eieren (Tic Tac Toe)

Leerdoelen

Na het maken van deze app wordt van je verwacht dat je:

  • weet hoe je een grid layout gebruikt
  • weet hoe je tags aan een view kunt koppelen en kunt gebruiken
  • met java een afbeelding aan een ImageView kunt koppelen
  • weet hoe je met behulp van de onClick property de view waarop door gebruiker is geklikt kunt opvragen en gebruiken in java
  • hoe je een gehele layout inclusief children op het scherm zichtbaar en onzichtbaar kunt maken
  • hoe je de tekst van een view kunt veranderen met java met de methode setText
  • weet hoe je kind-elementen van een layout kunt benaderen met de methode getChildAt(indexPositie) en hoe je met een for-lus door alle elementen van een layout kunt loopen.

De gebruikte afbeeldingen

Opdracht

Bekijk onderstaand filmpje en maak de app.

Gebruikte methodes/klassen

GridLayout

Hieronder zie je een deel van de gebruikte code voor de GridLayout. De achtergrond van de GridLayout is een plaatje. De GridLayout krijgt een id zodat we hem in java kunnen opvragen. De ImageViews worden gepositioneerd met behulp van rij- en kolomnummers. Iedere ImageView in de layout krijgt een tag zodat hij in java gemakkelijk te identificeren is als er door gebruiker op wordt geklikt. Iedere ImageView krijgt dezelfde methode onClick.

<GridLayout
        android:layout_width="match_parent"
        android:layout_height="360dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/bord"
        android:columnCount="3"
        android:rowCount="3"
        android:id="@+id/gridLayout">

        <ImageView
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_row="0"
            android:layout_column="0"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="20dp"
            android:onClick="setImg"
            android:tag="0"/>
        <ImageView
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_row="0"
            android:layout_column="1"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="20dp"
            android:onClick="setImg"
            android:tag="1"/>

        ...
        ...

</GridLayout>

In java implementeer je vervolgens de onClick property setImg door een methode met dezelfde naam te schrijven. De methode krijgt een parameter van het type View. Dit is de view waar door de gebruiker op is geklikt. Deze moet worden getypecast naar de juiste soort view, in dit geval een ImageView.

public void setImg(View view) {
    ImageView imageView = (ImageView) view;
    ...
}

Aan deze view kunnen we vervolgens een plaatje koppelen met behulp van de methode setImageResource. Welk plaatje aan de ImageView wordt gekoppeld is afhankelijk van welke speler aan de beurt is. Voor een aardig effect kun je uiteraard wat animatie toevoegen.

Tags gebruiken

Om bij te houden welke speler welke ImageView heeft gekozen wordt het spelverloop bijgehouden met behulp van een array van integers. Welke speler aan de beurt is wordt bijgehouden met een int variabele (1 of 2). Speler 1 begint, dus spelerActief wordt in de onCreate methode op 1 gezet.

int spelerActief;
int[] spelverloop = {0,0,0,0,0,0,0,0,0};

Met de tags die we aan de ImageViews hebben gegeven kunnen we de geklikte ImageView identificeren.

public void setImg(View view) {
    ImageView imageView = (ImageView) view;
    int index = Integer.parseInt(imageView.getTag().toString());
    //check of plaatje nog leeg is
    if (spelverloop[index] == 0) {
        spelverloop[index] = spelerActief;

        // set het juiste plaatje
        switch (spelerActief) {
            case 1:
                imageView.setTranslationY(-1000f);
                imageView.setImageResource(R.drawable.kruisje);
                imageView.animate().translationY(0f).setDuration(300);
                //TODO check einde spel
                spelerActief = 2;
                break;
            case 2:
                imageView.setTranslationY(-1000f);
                imageView.setImageResource(R.drawable.rondje);
                imageView.animate().translationY(0f).setDuration(300);
                //TODO check einde spel
                spelerActief = 1;
                break;
        }
    }
}

setText

De text van bijvoorbeeld TextViews, EditText velden en Buttons kun je in java beïnvloeden met de methode setText. De tekst van de layout die verschijnt als het spel is afgelopen bijvoorbeeld is afhankelijk van de uitkomst van het spel. In het volgende codefragment wordt met een hulpmethode geswitched over het attribuut spelergewonnen en afhankelijk daarvan wordt de juiste tekst uit het strings.xml bestand opgehaald en op de TextView gezet:

private void eindigSpel() {
    switch (spelerGewonnen) {
        case 0:
            eindeSpelTextView.setText(R.string.gelijk_spel);
            break;
        case 1:
            eindeSpelTextView.setText(R.string.winner_1);
            break;
        case 2:
            eindeSpelTextView.setText(R.string.winner_2);
            break;
    }
    eindeSpelLayout.setVisibility(View.VISIBLE);
}

Loopen door een Layout

Als een nieuw spel wordt gestart moeten alle plaatjes van de ImageViews weer worden verwijderd. Je kunt alle views binnen een layout (de zogenaamde children) benaderen met de methode getChildAt(indexpositie). Als je alle elementen van een layout wilt benaderen, dan gebruik je een for-lus:

public void nieuwSpel(View view) {
    GridLayout gridLayout = (GridLayout) findViewById(R.id.gridLayout);
    for (int i = 0; i < gridLayout.getChildCount(); i++) {
        ImageView imageView = (ImageView) gridLayout.getChildAt(i);
        imageView.setImageResource(0);
    }
    //TODO reset alle attributen naar hun startwaarde
}