Lekce 3 - Android Intenty a aktivity - SumActivity - Java kód
V minulé lekci, Android Intenty a aktivity - SumActivity - Součet čísel, jsme si připravili GUI aktivity pro součet 2 čísel.
Než začneme psát Java kód SumActivity
, vytvoříme rozhraní
pro deklarace všech konstant ukázkové aplikace Activities
.
V aplikaci máme totiž několik aktivit a nechceme každé definovat konstanty zvlášť. Některé budou určitě potřebovat ty samé. Proto je definujeme centrálně v jednom rozhraní.
Rozhraní pro konstanty
Ve struktuře projektu klikneme pravým tlačítkem na složku (viz. obrázek) a v menu přes New na Java Class:

V otevřeném okně New Java Class do řádku Name
napíšeme AppConstants
, v dalším řádku Kind vybereme
možnost Interface a potvrdíme tlačítkem OK:

Bude vytvořen soubor AppConstants.java
:
public interface AppConstants { }
Do tohoto souboru budeme postupně přidávat konstanty, použité v projektu.
Konstanta LOG_TAG
Hned přidáme konstantu pro tag zpráv Logcatu:
public interface AppConstants { String LOG_TAG = "Activities_log_tag"; }
Takto můžeme pak snadno poznat naše logy.
Přístup ke konstantám
Přístup ke konstantám je možný dvěma způsoby. První způsob je přímo, například voláním:
String tag = AppConstants.LOG_TAG;
Nebo může třída, ve které konstantu potřebujeme, implementovat
rozhraní AppConstants
, čímž získá přístup ke všem jeho
konstantám:
public class MyClass implements AppConstants { String tag = LOG_TAG; }
SumActivity.java
Vraťme se zpět k aktivitě SumActivity
. Nyní upravíme její
Java kód na následující:
public class SumActivity extends AppCompatActivity { EditText etNumber1, etNumber2; // Políčko pro zadání čísel k součtu Button btnSend; // Tlačítko pro odeslní čísel do SumResultActivity TextView labelResult; // Label pro zobrazení vráceného součtu zadaných čísel int number1, number2; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sum_activity); setTitle(R.string.sum_activity_title); etNumber1 = findViewById(R.id.etNumber1); etNumber2 = findViewById(R.id.etNumber2); labelResult = findViewById(R.id.labelResult); btnSend = findViewById(R.id.btnSend); btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { number1 = Integer.parseInt(etNumber1.getText().toString()); number2 = Integer.parseInt(etNumber2.getText().toString()); sendData(); } catch (NumberFormatException e) { Log.d(AppConstants.LOG_TAG, "NumberFormatException"); Log.d(AppConstants.LOG_TAG, e.getMessage()); showErrorToast(); } catch (NullPointerException e) { Log.d(AppConstants.LOG_TAG, "NullPointerException"); Log.d(AppConstants.LOG_TAG, e.getMessage()); showErrorToast(); } } }); } private void showErrorToast() { Toast.makeText(this, R.string.info_incorrect_entry, Toast.LENGTH_LONG).show(); } }
Pojďme si jej vysvětlit:
Kliknutí na tlačítko
V ActivityMain.java
jsme události kliknutí nastavili
příslušnými parametry tlačítek v XML a deklarací obslužné metody v Java
kódu. Zde to děláme pro změnu pouze Java kódem, přesněji přiřazením
OnClickListener
komponentám, na kterých budeme kliknutí
očekávat. Nastavení listeneru zde provádíme inline anonymní třídou. Na
tomto přístupu není nic špatného, ale má nevýhodu ve větším množství
Java kódu a v nemožnosti kód znovu použít.
Kliknutím na tlačítko Odeslat k výpočtu zadaná čísla
odesíláme do aktivity SumResultActivity
, jejímž úkolem je
čísla sečíst a výsledek odeslat zpět do aktivity SumActivity
.
Zadání uživatele v políčkách EditText
převádíme z typu
String
na typ int
voláním metody
parseInt()
třídy Integer
.
Během konverze může, v případě, že zadaný text obsahuje znak, který
není číslicí, dojít k výjimce NumberFormatException
. To je
první ze dvou důvodů, proč je tato část kódu "zabalena" do bloku
try
- catch
. Druhým důvodem je fakt, že řádek
etNumberOne.getText().toString()
může vyvolat výjimku
NullPointerException
. Zmíněné případné výjimky tedy
odchytáváme a můžeme na ně reagovat, aniž by došlo k pádu aplikace.
Otevření aktivity pro součet zadaných čísel
Po úspěšné konverzi vstupu voláme metodu sendData()
.
Přidejme si ji do třídy:
private void sendData() { }
Metodu zatím necháme prázdnou. Po vytvoření aktivity
SumResultActivity
(pro samotný součet čísel) kód metody
sendData()
doplníme.
startActivityForResult()
Metodu pro odpověď s výsledkem aktivity si teď přidejme:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == 1) { if (data != null) { if (data.hasExtra("result_from_activity_sum")) { labelResult.setText("" + data.getIntExtra("result_from_activity_sum", -1)); } else { labelResult.setText(R.string.info_error_loading_result); } } } } else if (resultCode == RESULT_CANCELED) { labelResult.setText(R.string.info_no_result); } }
Po zavření aktivity SumResultActivity
obdrží z této
aktivity SumActivity
odpověď voláním její metody
onActivityResult()
. S touto metodou získáme tři parametry:
requestCode
- Zde bude vrácena hodnota parametrurequestCode
z volání metodystartActivityForResult()
.resultCode
- Hodnota typuint
, která říká, jakým způsobem byla zavřená aktivita ukončena. Číselná hodnota je vyjádřena konstantou:RESULT_OK
v případě, že v zavřené aktivitě bylo, před jejím ukončením, zavolánosetResult(RESULT_OK, resultIntent)
.RESULT_CANCELED
obdržíme, pokud byla aktivita ukončena volánímsetResult(RESULT_CANCELED)
nebo tlačítkem Zpět. Toto bude brzy blíže vysvětleno při popisu aktivitySumResultActivity
.
data
- Zde nalezneme objekt třídyIntent
, vložený do parametru volánísetResult(RESULT_OK, resultIntent)
v zavírané aktivitě. Tím se dostáváme k použití intentu jako kontejneru primitivních dat. V intentu bez akce nalezneme data odeslaná aktivitouSumResultActivity
. Popis, jak tato data vytvořit, opět uvidíme ve výkladu o aktivitěSumResultActivity
.
V metodě onActivityResult()
jako první podmínkou
zjišťujeme, jak byla aktivita zavřena. Pokud parametr resultCode
obsahuje hodnotu RESULT_OK
, další postup určujeme podle
int requestCode
. My zde máme pouze jedinou možnost.
Dále v podmínce testujeme, zda příchozí intent obsahuje nějaká
návratová data. Očekáváme, že nám bude vrácen součet dvou čísel,
odeslaných do SumResultActivity
. Pokud je podmínka splněna,
zjišťujeme voláním data.hasExtra()
, zda data obsahují uvedené
klíče, vyjádřeným textovým řetězcem. Pod tímto klíčem jsou data do
návratového intentu vložena v SumResultActivity
. Pokud data tyto
klíče obsahují, rovnou nastavujeme TextView
, který je určen
pro zobrazení výsledku součtu v SumActivity
.
Úprava Java kódu hlavní aktivity
Nyní, když máme hotovou aktivitu SumActivity
, doplníme v
MainActivity
kus kódu do první větve konstrukce
switch
v metodě click()
. Tímto bude první
tlačítko s textem Součet čísel ukázkové aplikace funkční.
Metoda click()
bude nyní vypadat takto:
public void click(View view) { switch (view.getId()) { case R.id.btnSumActivity: Intent intentSumActivity = new Intent(MainActivity.this, SumActivity.class); startActivity(intentSumActivity); break; case R.id.btnMapActivity: break; case R.id.btnPhoneActivity: break; case R.id.btnPhotoActivity: break; case R.id.btnShareActivity: break; case R.id.btnITnetwork: Intent webIntent = new Intent(Intent.ACTION_VIEW); webIntent.setData(Uri.parse("https://www.itnetwork.cz/")); if (webIntent.resolveActivity(getPackageManager()) != null) { startActivity(webIntent); } break; } }
V doplněné první větvi přepínače switch
, v prvním
řádku, vytváříme explicitní intent pro otevření aktivity
SumActivity
. V druhém řádku tuto aktivitu, voláním metody
startActivity()
, otevíráme.
Jen připomenu, že metoda click()
je námi deklarovaná metoda
a v XML návrhu hlavní aktivity je všem tlačítkům nastavena jako obsluha
události kliknutí takto: android:onClick="click"
.
V příští lekci, Android Intenty a aktivity - SumResultActivity, vytvoříme vzhled grafického uživatelského rozhraní aktivity, do které budeme odesílat uživatelem zadaná čísla, určená k součtu.
Komentáře
Zatím nikdo nevložil komentář - buď první!