Lekce 6 - Android programování - Implementace Kotlin kódu kalkulačky
V minulé lekci, Android programování - První aplikace, návrh kalkulačky, jsme se věnovali návrhu jednoduché kalkulačky.
V dnešní lekci Android tutoriálu si konečně ukážeme Kotlin kód budoucí kalkulačky a dostaneme se tedy k programování!
Kotlin kód aplikace
Kód budeme psát do souboru MainActivity.kt
, který byl
vygenerován Android Studiem při vytváření projektu kalkulačky. Při
prvním pohledu do MainActivity.kt
uvidíme tento kód,
obsahující jedinou metodu:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
Zatím jediné dva řádky v onCreate()
volají metodu předka a
nastavují vzhled grafického uživatelského rozhraní odkazem na XML soubor
návrhu activity_main.xml
.
Nyní si ukážeme několik dalších částí kódu, které budeme do
MainActivity.kt
postupně přidávat.
Deklarace proměnných
V souboru MainActivity.kt
, nad metodou onCreate()
,
nejprve deklarujeme proměnné pro uložení referencí na ty komponenty z XML
návrhu, se kterými budeme pracovat:
private lateinit var etNumber1: EditText private lateinit var etNumber2: EditText private lateinit var spinnerOperation: Spinner private lateinit var labelResult: TextView
Kdybychom nepoužili klíčové slovo lateinit
, museli bychom
atribut nastavit na null
. Klíčové slovo lateinit
nám umožňuje k atributu nepřiřazovat hodnotu. Při volání metody na
neinicializovaný atribut nám způsobí výjimku
UninitializedPropertyAccessException
. Tohle si později
ukážeme.
Všimněme si, že chybí proměnná pro tlačítko =
. Jediná
práce s tlačítkem je nastavení obslužné metody při kliknutí. A protože
jsme toto udělali již v minulé části, přímo v XML návrhu tlačítka
parametrem android:onClick="calculate"
, nemusíme se o to již
starat v Kotlin kódu. Lze říci, že jsme tím také ušetřili pár řádků
kódu, protože v Kotlin kódu je tato činnost pracnější.
Metoda onCreate()
Metoda onCreate()
je tou nejdůležitější metodou naší
aplikace. Zde totiž, po spuštění aplikace, vše začíná.
Inicializace proměnných
Metodě onCreate()
tedy nyní doplníme inicializaci
proměnných na potřebné komponenty z XML návrhu. Díky tomu budeme moci s
těmito objekty pracovat v Kotlin kódu. Umožní nám získávat obsah
zadávacích políček, nastavovat text s výsledkem výpočtu komponentě
TextView
atd.:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) etNumber1 = findViewById(R.id.etNumber1) etNumber2 = findViewById(R.id.etNumber2) spinnerOperation = findViewById(R.id.spinnerOperation) labelResult = findViewById(R.id.labelResult) }
Jistě jste si všimli, že metoda onCreate()
přijímá jeden
parametr savedInstanceState
. Ten je po spuštění aplikace
null
. Slouží pro ukládání stavu aplikace. Například po
změně orientace zařízení tento parametr již null
nebude a
bude obsahovat některá data aplikace.
Položky pro Spinner
Na konec metody připíšeme další kód pro přípravu položek pro
Spinner
:
val operatorsArray = resources.getStringArray(R.array.operators)
Vytváříme zde pole textových řetězců operatorsArray
se
čtyřmi operátory: ["+", "-", "*", "/"]
pro početní operace
kalkulačky, které budeme uživateli nabízet v rozbalovacím menu
Spinner
. Toto pole neinicializujeme přímo, ale hodnotami z pole
operators
, nacházejícího se v resources
v souboru
res/values/strings.xml
. Pojďme si tam hodnoty deklarovat.
Úprava souboru
strings.xml
Soubor strings.xml
byl při vytvoření projektu automaticky
vygenerován Android Studiem a my do něj přidáme deklaraci zmíněného pole
operators
:
<resources> <string name="app_name">SimpleCalc</string> <string-array name="operators"> <item>+</item> <item>-</item> <item>*</item> <item>/</item> </string-array> </resources>
První položka
<string name="app_name">SimpleCalc</string>
v souboru
strings.xml
byla automaticky vygenerována při vytvoření
projektu a obsahuje textový řetězec s názvem aplikace, který je zobrazován
například v toolbaru aplikace nebo v seznamu nainstalovaných aplikací v
uživatelově zařízení.
Všechny textové řetězce se v Android aplikacích píší do
strings.xml
, aby se aplikace dala jednoduše přeložit do více
jazyků. U znamének to zatím nedává smysl, ale co kdybychom tam přidali pak
nějakou další operaci, která by byla pojmenovaná slovem.
Doplnění metody
onCreate()
Vrátíme se do metody onCreate()
a pokračujeme:
val list = operatorsArray.toList() val dataAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, list)
Pole možností dosadíme do komponenty Spinner
pomocí
adaptéru. Pokud jste dělali formulářové aplikace v
Java Swing, je to podobné. Z vytvořeného pole operatorsArray
vytváříme kolekci List
, kterou předáme adaptéru pro
Spinner
, jehož úkolem je správa položek zobrazovaných
uživateli. Konstruktor adaptéru přijímá tři parametry:
- referenci na aktuální kontext,
- referenci na XML návrh vzhledu té položky
Spinner
, která je aktuálně vybrána, - kolekci s položkami
Spinner
.
Dalším řádkem spinneru nastavujeme vzhled položek zobrazených v jeho rozbalovacím menu:
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
I zde, podobně jako v případě vybrané položky, volíme defaultní
vzhled položek menu. V posledním řádku metody onCreate()
komponentě Spinner vytvořený adaptér přiřadíme:
spinnerOperation.adapter = dataAdapter
Metoda calculate()
Nyní si popíšeme jedinou naší vlastní metodu, kterou přidáme do
souboru MainActivity.kt
a která bude obsluhovat událost kliknutí
na tlačítko =
. Jak jsme si již řekli, tlačítko již máme v
XML na metodu napojené pomocí atributu
android:onClick="calculate"
.
Aby metoda calculate()
mohla na událost kliknutí reagovat,
musí přijímat parametr typu View
. A ten bude obsahovat, při
volání metody, referenci na ten objekt z XML, od kterého událost přišla.
Pokud tento parametr bude chybět, dojde po kliknutí na tlačítko
=
k pádu aplikace s chybou IllegalStateException
:
Kód metody calculate()
máme zde:
fun calculate(view: View) { val number1: Double val number2: Double var result = 0.0 try { number1 = etNumber1.text.toString().toDouble() number2 = etNumber2.text.toString().toDouble() if (spinnerOperation.selectedItem.equals("+")) { result = number1 + number2 } else if (spinnerOperation.selectedItem.equals("-")) { result = number1 - number2 } else if (spinnerOperation.selectedItem.equals("*")) { result = number1 * number2 } else if (spinnerOperation.selectedItem.equals("/")) { if (number2 == 0.toDouble()) { labelResult.text = "NULOU DĚLIT NELZE!" return; } result = number1 / number2; } val nf = DecimalFormat("#.##") labelResult.text = nf.format(result) } catch (e: java.lang.NumberFormatException) { labelResult.text = "Chybné zadání..." } }
V úvodu metody calculate()
deklarujeme proměnné
number1
a number2
, do kterých budeme ukládat
uživatelem zadaná čísla a proměnnou result
pro uložení
výsledku výpočtu.
Další blok kódu je umístěn v bloku try - catch
pro
odchycení případné výjimky NumberFormatException
, ke které
dojde při zadání nečíselné hodnoty do jednoho z políček. Konkrétně by
k chybě došlo při převodu datových typů, kdy bude na místě výsledku
zobrazeno hlášení o chybném zadání. Do proměnných number1
a
number2
ukládáme obsah zadávacích políček, který načteme
jako text a následně jej převedeme na Double
.
Po úspěšném převodu datových typů dochází podmínkou if
k větvení programu do čtyř možných scénářů podle typu matematické
operace, která je uživatelem vybrána. Ve všech případech do proměnné
result
ukládáme výsledek výpočtu. Pokud je požadovanou
operací dělení, bude druhé zadané číslo otestováno na nulovou hodnotu.
Při nulové hodnotě druhého čísla by došlo k porušení jedenáctého
přikázání - dělení nulou Pokud uživatel bude chtít dělit nulou, vypíšeme mu, místo
výsledku, hlášku o tom, že dělit nulou nelze a metoda bude ukončena
příkazem return
.
Po provedení úspěšného výpočtu přichází čas k zobrazení
výsledku. Než výsledek zobrazíme v komponentě TextView
,
"proženeme" jej třídou DecimalFormat
, která výsledek
zaokrouhlí na definovaný počet desetinných míst. Až po této úpravě
TextView
nastavujeme text v podobě získaného výsledku
výpočtu, aby byl zobrazen uživateli.
Kód kalkulačky tímto máme hotový
V následujícím kvízu, Kvíz - Tvorba GUI pro Android aplikace v Kotlin, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.