Android-sovelluksen visuaalinen ilme perustuu teemoihin, jotka määrittävät käyttöliittymän elementtien ulkoasun. Yksi haaste sovelluskehityksessä on varmistaa, että sovellus näyttää ja toimii hyvin eri Android-versioilla, koska käyttöjärjestelmän versiot tarjoavat erilaisia teemavaihtoehtoja ja ominaisuuksia. Tämä luku käsittelee, miten sovellukseen voidaan määrittää automaattisesti sopiva teema käyttäjän Android-version perusteella.

Ensinnäkin teema määritellään XML-tyylitiedostossa (styles.xml), joka sijaitsee res/values-kansiossa. Uuden teeman luomiseksi kannattaa periä olemassa oleva perus-teema kuten AppTheme ja tehdä siihen tarvittavat lisäykset, esimerkiksi määrittää, että ikkuna toimii kelluvana dialogina asettamalla ominaisuus windowIsFloating. Tämän jälkeen sovelluksen AndroidManifest.xml-tiedostossa Activitylle annetaan uusi teema käyttöön theme-attribuutilla. Näin Activity käynnistyy halutulla teemalla.

Koska Androidin eri versioissa on eri teemavaihtoehtoja, on järkevää luoda erilliset tyylitiedostot eri API-versioille. Android tukee kolmea pääteemaa: Gingerbreadia vanhemmille versioille on perinteinen Theme, Honeycombilta (API 11) lähtien on Theme.Holo ja Lollipopista (API 21) alkaen Theme.Material. Näiden eri teemojen käyttämiseksi resurssihakemistoihin lisätään versionmukaiset arvot, kuten values-v11 ja values-v21. Kussakin hakemistossa sijaitseva styles.xml määrittelee version mukaisen teeman.

Sovelluksen koodi määrittelee, että Activity periytyy suoraan Activity-luokasta eikä käytä AppCompatActivitya, jotta teemavalinta ei perustu AppCompat-kirjastoihin vaan suoraan Androidin resurssivalintaan. Sovelluksen teema asetetaan AndroidManifestissa viittaamaan yhteiseen teemanimelle, joka on määritelty kolmessa eri tyylitiedostossa. Androidin resurssijärjestelmä valitsee automaattisesti oikean teemaversion ajon aikana käyttäjän laitteessa olevan API-tason perusteella.

Tämä menetelmä tarjoaa joustavuutta ja yhteensopivuutta eri laiteympäristöissä, sillä se varmistaa, että käyttäjä saa aina käyttöjärjestelmänsä mukaisen modernin ja optimoidun käyttöliittymän. Vastaavasti voidaan hyödyntää myös muita resurssivalinnan kriteerejä, kuten näytön kokoa, resoluutiota tai suuntaa, jolloin sovelluksen ulkoasu ja toiminta mukautuvat laajasti erilaisiin laitekokoonpanoihin.

On tärkeää huomata, että vaikka teeman määrittelyssä voi olla houkuttelevaa lisätä ominaisuuksia suoraan perus-teemaan, erillisten teemojen luominen eri aktiviteeteille tai versiokohtaisille resursseille antaa hallinnan säilyä tarkempana ja estää esimerkiksi kaikkien aktiviteettien näkymistä dialogityylisinä, mikä ei välttämättä aina ole tarkoituksenmukaista.

Lisäksi teemojen ylläpidossa tulee huomioida, että Androidin eri versioiden teemat eroavat paitsi visuaalisesti myös käyttäytymiseltään, mikä saattaa vaikuttaa esimerkiksi painikkeiden tai valikoiden ulkoasuun ja toiminnallisuuksiin. Tästä syystä teemojen testaus eri laiteympäristöissä on olennainen osa kehitysprosessia.

Teemojen automaattinen valinta käyttäjän Android-version mukaan on siis olennainen osa nykyaikaista sovelluskehitystä. Se parantaa käyttökokemusta ja tekee sovelluksesta kilpailukykyisemmän markkinoilla, joissa käyttäjäodotukset visuaalisuudesta ja suorituskyvystä kasvavat jatkuvasti.

Miten luoda ja hallita toimintoja Android-sovelluksessa käyttäen Activity-luokkaa

Android-sovelluksen kehittäminen sisältää usein monivaiheisten toimintojen hallintaa, jotka ovat keskeisiä sovelluksen käytettävyyden ja sujuvuuden kannalta. Yksi tärkeimmistä peruskonsepteista on toimintojen (Activities) luominen ja niiden välisen navigoinnin hallinta. Tässä osassa käymme läpi, kuinka luoda uusi toiminto, siirtyä toiseen toimintaan ja siirtää tietoja näiden toimintojen välillä.

Aloitamme luomalla toisen toiminnon sovellukseen. Avaa Android Studio ja navigoi projektiisi. Valitse File | New | Activity | Blank Activity ja nimeä uusi toiminto haluamallasi tavalla, esimerkiksi SecondActivity. Tämä luo uuden toiminnon ja sen liittyvät tiedostot.

Kun toinen toiminto on luotu, avaa MainActivity.java ja lisää sinne seuraava koodi:

java
public void onClickSwitchActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class); startActivity(intent); }

Tämä funktio käynnistää toisen toiminnon, kun siihen liittyvä nappi painetaan. Intent-objekti luo yhteyden ensimmäisen ja toisen toiminnon välille. Intentin avulla ilmoitamme Android-järjestelmälle, että haluamme siirtyä toiseen Activity-luokkaan, tässä tapauksessa SecondActivity-luokkaan.

Seuraavaksi luodaan nappi, joka käynnistää toisen toiminnon. Avaa activity_main.xml ja lisää siihen seuraava XML-koodi:

xml
<Button android:id="@+id/buttonSwitch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Launch Second Activity" android:onClick="onClickSwitchActivity"/>

Kun koodi on valmis, voit ajaa sovelluksen ja huomata, että napin painaminen avaa toisen toiminnon.

Jatkamme toisen toiminnon parissa. SecondActivity.java-tiedostossa lisää seuraava funktio, joka sulkee toisen toiminnon ja palaa ensimmäiseen:

java
public void onClickClose(View view) {
finish(); }

Tämä funktio käyttää finish()-metodia, joka ilmoittaa järjestelmälle, että nykyinen toiminto on suoritettu ja se voidaan sulkea. finish() ei palauta meitä suoraan alkuperäiseen toimintaan, mutta se sulkee nykyisen toiminnon ja palauttaa meidät taustalle, joka on asetettu Androidin toimintapinoon.

Lisäksi SecondActivity-toiminnolle lisätään sulkemisnappi. Avaa activity_second.xml ja lisää seuraava koodi:

xml
<Button
android:id="@+id/buttonClose" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Close" android:onClick="onClickClose"/>

Kun sovellus on ajossa, voit nähdä, että molemmat napit toimivat kuten odotettiin: ensimmäinen avaa toisen toiminnon ja toinen sulkee sen ja palauttaa takaisin ensimmäiseen toimintaan.

Kun tarkastellaan tätä toimintojen hallintaa tarkemmin, huomataan, että Intent-objekti on keskeinen väline tietojen siirtämisessä toimintoja välillä. Voimme käyttää Intent-objektia myös tietojen välittämiseen toiseen toimintaan, kuten seuraavaksi käymme läpi.

Tietojen välittäminen toimintoihin

Sovelluksissa on usein tarpeen siirtää tietoja yhdestä toiminnosta toiseen. Tämä voidaan tehdä käyttämällä Intent-objektia ja erityisesti putExtra()-metodia. Tässä esimerkissä lisätään päätoimintoon EditText-kenttä, johon käyttäjä voi kirjoittaa tekstiä, ja tämä teksti lähetetään toiseen toimintaan.

Avaa activity_main.xml ja poista vanha Button-elementti. Lisää tilalle seuraava XML-koodi:

xml
<EditText android:id="@+id/editTextData" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter text" />

Seuraavaksi, MainActivity.java-tiedostossa, muokkaa onClickSwitchActivity()-metodia seuraavasti:

java
public void onClickSwitchActivity(View view) {
EditText editText = (EditText) findViewById(R.id.editTextData); String text = editText.getText().toString(); Intent intent = new Intent(this, SecondActivity.class); intent.putExtra(Intent.EXTRA_TEXT, text); startActivity(intent); }

Nyt, kun käyttäjä syöttää tekstin päätoimintoon ja painaa nappia, tämä teksti lähetetään toiselle toiminnolle.

Siirrytään nyt SecondActivity.java-tiedostoon ja lisäämme koodin, joka vastaanottaa tämän tiedon ja näyttää sen ruudulla. Avaa SecondActivity.java ja muokkaa onCreate()-metodia seuraavasti:

java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); TextView textView = (TextView) findViewById(R.id.textViewText); if (getIntent() != null && getIntent().hasExtra(Intent.EXTRA_TEXT)) { textView.setText(getIntent().getStringExtra(Intent.EXTRA_TEXT)); } }

Tämä koodi tarkistaa, onko Intent-objektissa lisättyjä tietoja, ja jos on, se asettaa nämä tiedot TextView-komponenttiin. Nyt päätoiminnosta lähetetty teksti tulee näkyville toisessa toiminnossa.

Tärkeää on huomata, että Androidin Intent-objekti tukee monia eri tietotyyppejä. Voimme lähettää esimerkiksi merkkijonoja, lukuja, tai jopa monimutkaisempia tietorakenteita. putExtra()-metodi toimii nimimerkki/arvo-pareina, joissa nimeä käytetään avaimena ja arvoa käytetään tiedon esittämiseen. On tärkeää käyttää samaa nimeä, kun luetaan tietoja takaisin getStringExtra()-metodilla.

Tässä vaiheessa on hyvä huomata, että vaikka tässä esimerkissä keskitymme tekstin siirtämiseen, Androidin Intent-objekti on paljon joustavampi. Se tukee monenlaisia tietotyyppejä, mukaan lukien int, boolean ja Serializable-objektit, joita voi käyttää tiedon välittämiseen sovelluksen eri osien välillä.