NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 6 - Android Intenty a aktivity - Java kód SumResultActivity

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

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

Java kód SumResultActivity

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

public class SumResultActivity 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.sum_result_activity);
        setTitle(R.string.sum_result_activity_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í proměnnou 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 aktivity SumActivity

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 SumActivity.

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. Tato výjimka bude vyvolána v případě, že "příchozí" intent, uložený do proměnné incomingIntent, bude obsahovat hodnotu null. Ve chvíli, kdy bychom na proměnné incomingIntent, s hodnotou null, zavolali metodu getIntExtra(), došlo by bez ošetření výjimky k pádu aplikace za běhu.

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 SumActivity je realizováno opět Java kódem, podobně jako v SumActivity. 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í :)

Při porovnání tohoto způsobu obsluhy události s anonymní třídou v SumActivity 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 SumActivity

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 SumActivity, 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 SumActivity.

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

Deklarace aktivit v AndroidManifest.xml

I přes to, že zatím nemáme dokončenou deklaraci metody sendData() v aktivitě SumActivity, je možné naší aplikaci Activities spustit. Pokud tak učiníme a pokusíme se otevřít prvním tlačítkem SumActivity, 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:

Android Intenty a aktivity

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

Android Intenty a aktivity

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 SumActivity a SumResultActivity. Obě tedy do manifestu přidáme následujícím kódem za deklaraci MainActivity:

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

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

Upravený soubor AndroidManifest.xml bude tedy vypadat takto:

Android Intenty a aktivity

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:

Android Intenty a aktivity Android Intenty a aktivity

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

V příští lekci, Android Intenty a aktivity - Zobrazení SumResultActivity, si napíšeme kód pro zobrazení aktivity SumActivity. V aktivitě SumResultActivity se naučíme používat odkazy na textové řetězce.


 

Předchozí článek
Android Intenty a aktivity - SumResultActivity
Všechny články v sekci
Android Intenty a aktivity
Přeskočit článek
(nedoporučujeme)
Android Intenty a aktivity - Zobrazení SumResultActivity
Článek pro vás napsal Pavel
Avatar
Uživatelské hodnocení:
1 hlasů
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity