MS Office week
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
50 % bodů zdarma na online výuku díky naší Slevové akci!

Lekce 5 - Android Intenty a aktivity - Java kód ActivitySum

Minule, v lekci Android Intenty a aktivity - ActivitySum, jsme vytvořili XML návrh GUI aktivity ActivitySum, přijímající z ActivityA dvě čísla.

Celá dnešní lekce bude, jak asi tušíte, o Java kódu ActivitySum.

Java kód ActivitySum

Upravíme si jej tedy do následující podoby, kterou si hned podrobně vysvětlíme:

public class ActivitySum extends AppCompatActivity {

    TextView labelNumber1;
    TextView labelNumber2;
    TextView labelResult;
    Button btnSend;

    int number1 = 0;
    int number2 = 0;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sum);
        setTitle(R.string.activity_sum_title);

        labelNumber1 = findViewById(R.id.labelNumber1);
        labelNumber2 = findViewById(R.id.labelNumber2);
        labelResult = findViewById(R.id.labelResult);
        btnSend = findViewById(R.id.btnSend);

        btnSend.setOnClickListener(clickListener);

        try {
            Intent incomingIntent = getIntent();

            number1 = incomingIntent.getIntExtra("number_1", 0);
            number2 = incomingIntent.getIntExtra("number_2", 0);

            labelNumber1.setText("" + number1);
            labelNumber2.setText("" + number2);
            labelResult.setText("" + (number1 + number2));
        } catch (NullPointerException e) {
            labelNumber1.setText("?");
            labelNumber2.setText("?");

            Toast.makeText(this, R.string.incoming_intent_data_error, Toast.LENGTH_LONG).show();
        }
    }
}

Chybějící metodu clickListener() si doplníme za chvíli.

Máme zde připravené atributy pro jednotlivé komponenty aktivity, které si inicializujeme v onCreate(). Také zde máme atributy pro uchování 2 čísel, která ale byla zadána v předchozí aktivitě. Dostáváme se k oné zajímavé části.

Příjem dat z ActivityA

V každé aktivitě získáme voláním getIntent() intent, kterým byla daná aktivita otevřena. My toto provádíme v metodě onCreate() a intent ukládáme do proměnné incomingIntent. Z ní pak pomocí klíčů získáme naše čísla určená k součtu. Zadáváme samozřejmě ty klíče, pod které jsme si data uložili v ActivityA.

Získané hodnoty pak zobrazujeme ve dvou TextView a ve třetím zobrazujeme jejich součet. Celý popsaný postup je v bloku try - catch, kterým odchytáváme případnou výjimku NullPointerException.

Událost kliknutí na tlačítko

Máme zde také další slíbený alternativní způsob obsluhy kliknutí na tlačítko.

Odeslání výsledku součtu zpět do ActivityA je realizováno opět Java kódem, podobně jako v ActivityA. Tenkrát jsme tlačítku přiřadili inline zápisem OnClickListener vytvořením anonymní třídy. Říkali jsme si, že tento přístup neumožňuje opětovné použití kódu. Zde bude postup podobný. Rozdíl bude v tom, že vytvoříme instanci listeneru, kterou lze přiřadit libovolnému počtu elementů.

Do kódu za deklaraci proměnných přidáme:

View.OnClickListener clickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnSend) {
            Intent resultIntent = new Intent();
            resultIntent.putExtra("result_from_activity_sum", number1 + number2);
            setResult(RESULT_OK, resultIntent);
            finish();
        }
    }
};

Tento listener v metodě onCreate() nastavujeme jedinému tlačítku. Listener povinně přepisuje metodu onClick(), která je volána s parametrem typu View. Toto View je referencí na element, který byl v GUI stisknut.

V metodě onClick() pak už jen testujeme, zda se ID stisknutého elementu rovná ID tlačítka pro odeslání odpovědi (tedy zda událost kliknutí vyvolalo toto tlačítko).

Protože jsme tento listener přiřadili pouze jedinému objektu, není tato podmínka ani nutná, protože jiná možnost nastat nemůže. Je ji ovšem vhodné uvést, protože když bychom někdy přidali nějaký další klikací prvek, mohli bychom na ni zapomenout a takové chyby se špatně hledají :)

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Při porovnání tohoto způsobu obsluhy události s anonymní třídou v ActivityA je zřejmé, že tento má výhodu ve své znovupoužitelnosti. Ale stále má nevýhodu ve větším množství a menší přehlednosti, než u způsobu s atributem android:onClick přímo v XML.

Odeslání odpovědi do ActivityA

Po kliknutí se chceme vrátit do předchozí aktivity a poslat do ni výsledek. Popsaný OnClickListener v metodě onClick() tedy vytváří intent, který neobsahuje žádnou akci. Zde totiž vytváříme intent pouze za účelem přenosu dat mezi aktivitami. V dalším řádku intentu tato data nastavujeme s klíčem z textového řetězce. Díky tomuto klíči data vyzvedneme v ActivityA, kam je pošleme.

Dalším řádkem voláme metodu setResult(). Minule jsme si v této souvislosti popisovali dvě konstanty:

  • RESULT_OK a
  • RESULT_CANCELED.

Druhým parametrem je vytvořený intent s daty pro ActivityA.

Posledním řádkem aktivitu ActivitySum zavřeme a vrátíme se zpět do ActivityA.

Deklarace aktivit v AndroidManifest.xml

Pokud nyní naši aplikaci Activities spustíme a pokusíme se otevřít prvním tlačítkem ActivityA, dojde k pádu aplikace s výjimkou ActivityNotFoundException. V Android Studiu, pohledem do logcatu, uvidíme s nastaveným filtrem na zobrazení errorů něco takového:

Ve výpisu logcatu je dokonce upozornění na to, že aktivita není deklarována v souboru manifestu. Otevřeme tedy soubor AndroidManifest.xml:

Na obrázku je vidět obsah tohoto souboru po jeho automatickém vygenerování Android Studiem při vytvoření nového projektu. Do této chvíle nebylo nutné tento soubor jakkoliv upravovat.

Po přidání jakékoliv další aktivity do projektu je nutné ji v manifestu deklarovat!

My jsme vytvořili aktivity ActivityA a ActivitySum. Obě tedy do manifestu přidáme následujícím kódem za deklaraci MainActivity:

<activity
    android:name=".ActivityA"
    android:parentActivityName=".MainActivity">
</activity>

<activity
    android:name=".ActivitySum"
    android:parentActivityName=".MainActivity">
</activity>

Upravený soubor AndroidManifest.xml bude tedy vypadat takto:

parentActivityName

Atribut android:parentActivityName=".MainActivity" není povinný. Slouží pro zobrazení šipky v levé části toolbaru aktivity. Tato šipka slouží pro navigaci zpět do té aktivity, která je uvedena v hodnotě atributu. Následující obrázky ukazují rozdíl - první zobrazuje stav bez parametru a druhý s parametrem:

Všimněte si že v kódu manifestu z ActivitySum se touto šipkou vracíme přímo do hlavní aktivity a ne do ActivityA.

Používání odkazů na řetězce

Jistě jste si všimli nastavování textu zobrazovaným zprávám a objektům TextView. Nemělo by vás překvapit, že text není nastaven "na tvrdo", ale je použit odkaz do resources projektu.

Při vytvoření projektu Android Studio, spolu s dalšími soubory, vygeneruje soubor strings.xml ve složce res/values/. Ten slouží k ukládání textových řetězců, které tak lze v kódu použít vícekrát a na které v kódu odkazujeme. Je tak zejména kvůli centralizaci všech řetězců na jedno místo, čímž můžeme pak aplikaci jednoduše přeložit do jiného jazyka.

Pojďme si na příkladu ukázat, jak snadno lze v Android Studiu z použitého textového řetězce vytvořit položku v resources. V metodě onCreate() máme blok try - catch, kterým ošetřujeme vznik výjimky, při které bude uživateli zobrazena zpráva:

Toast.makeText(this, R.string.incoming_intent_data_error, Toast.LENGTH_LONG).show();

Takto by vypadala předchozí ukázka bez použití odkazu do resources:

Toast.makeText(this, "Chyba přijatých dat...", Toast.LENGTH_LONG).show();

Chceme-li z textového řetězce snadno vytvořit odkaz na, zatím neexistující, položku v res/values/strings.xml, klikneme na řetězec tak, aby na něm byl kurzor. Vlevo se objeví žlutá žárovka:

Na tuto žárovku klikneme levým tlačítkem a v menu zvolíme Extract string resource:

V otevřeném okně Extract Resource s předvyplněným textovým řetězcem napíšeme do prvního řádku název, pod jakým bude text uložen v souboru strings.xml, a potvrdíme tlačítkem OK:

Na konec souboru strings.xml bude přidán nový řádek:

Stejný způsob použijeme i v XML návrhu GUI a nastavovali bychom takto i barvy. Nastavíme-li někde nějakému elementu barvu přímo, můžeme ji později, pomocí žluté žárovky, extrahovat do souboru res/values/colors.xml stejně jako v případě textových řetězců.

Již umíme otevírat jiné aktivity a předávat data mezi nimi. V dalších lekcích kurzu si popíšeme funkce ostatních tlačítek ukázkové aplikace Activities. Prvních pět tlačítek bude explicitními intenty otevírat námi vytvořené aktivity. Každá z těchto aktivit bude mít nějakou funkčnost, spočívající ve vytváření implicitních intentů, zapojujících do hry i systém a jeho defaultní aktivity, jako např. zobrazení mapy, odesílání SMS nebo fotoaparát.

Příště, v lekci Android Intenty a aktivity - Aktivita B - Zobrazení mapy, vytvoříme ActivityB pro zobrazení zeměpisných souřadnic na mapě.


 

Předchozí článek
Android Intenty a aktivity - ActivitySum
Všechny články v sekci
Android Intenty a aktivity
Článek pro vás napsal lupa.lupa
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Aktivity (2)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!