NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

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:

Android - Tvorba mobilních aplikací v Kotlin

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.

Předchozí článek
Android programování - První aplikace, návrh kalkulačky
Všechny články v sekci
Android - Tvorba mobilních aplikací v Kotlin
Přeskočit článek
(nedoporučujeme)
Kvíz - Tvorba GUI pro Android aplikace v Kotlin
Článek pro vás napsal Marek Urbańczyk
Avatar
Uživatelské hodnocení:
12 hlasů
Autor se věnuje programování v Kotlinu, Javě. Má také zkušenosti s C#.
Aktivity