Postoji nekoliko načina da se doda slika u našu aplikaciju. Jedan način podrazumeva da sliku koju želimo postavimo u odgovarajući direktorijum i potom referišemo na nju unutar activity_main.xml fajla, na sličan način kao što smo kada smo uređivali niske. Drugi način je dodavati slike direktno u kodu u Kotlinu. Drugi način je teži za praćenje i preporučuje se da se ne koristi ako su nam sve slike već date, već samo u situacijama ako, recimo, naš program pravi sliku.
Slike se mogu zadati u XML fajlu koji ima formu kao sliek na sledećem linku. Ovaj pristup je dobar kada imamo vektorske slike i njegova prednost je to što se slika može smanjivati i povećavati bez gubitka podataka. Takođe, slike se mogu zadati i u drugim formatima, od kojih su prihvaćeni PNG, JPG i GIF. Preferira se da se koristi PNG, a GIF se ne preporučuje.
U prvom načinu, sliku zapisanu u XML ili nekom drugom fajlu dodajemo u folder src/main/res/drawables. Potom se pozicioniramo u naš activity_main.xml fajl i dodamo ImageView tamo gde želimo, na sličan način kao što smo dodavali dugmiće. Kao i kod Button. ImageView isto može da zada veličinu i poziciju. Recimo, sledeći kod dodaje sliku koja se nalazi u fajlu slika.xml tako da bude centrirana horizontalno i da bude onoliko velika koliko i njen sadržaj:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/slika" />
Kao i sa dugmetom i ostalim objektima, potrebno je povezati sliku sa objektom klase ImageView da bi mogle promene da se vrše nad slikom u kodu. Na jednostavnom primeru ćemo pokazati kako ovo funkcioniše. Recimo, imamo tri slike: slika1.png, slika2.png i slika3.png koje smo postavili u drawables folder. Želimo klikom na dugme da smenjujemo slike.
var brojac = 0 val dugme: Button = findViewById(R.id.id_za_dugme) dugme.setOnClickListener { // instanciranje slike val slika : ImageView = findViewById(R.id.id_za_sliku) // brojac govori koja je slika u pitanju brojac = (brojac + 1) % 3 val izvor = when (brojac) { 0 -> R.drawable.slika1 1 -> R.drawable.slika2 else -> R.drawable.slika3 } slika.setImageResource(izvor) }
Ovaj kod, iako jednostavan, ima ozbiljnu manu. Naime, tokom svakom klika dugmeta, slika se iznova povezuje sa objektom slika, što smanjuje performanse. Drugo rešenje podrazumeva da se povezivanje vrši samo jednom izvršavanja setOnClickListener metoda, a da se u tom metodu samo pozivaju. Najlepše rešenje je da se, pre metoda onCreate, deklariše slika na sledeći način:
lateinit var slika : ImageView
Sada bi naš kod za dugme radio ovako:
slika = findViewById(R.id.id_za_sliku) var brojac = 0 val dugme: Button = findViewById(R.id.id_za_dugme) dugme.setOnClickListener { // brojac govori koja je slika u pitanju brojac = (brojac + 1) % 3 val izvor = when (brojac) { 0 -> R.drawable.slika1 1 -> R.drawable.slika2 else -> R.drawable.slika3 } slika.setImageResource(izvor) }
Razlog zašto je dodat modifikator lateinit je zato što mi ne znamo tačno u kom trenutku će objekat biti učitan i da li će povezivanje biti izvršeno kada se klikne na dugme. Kada se sa objekat deklariše kao lateinit, kompajleru se obećava da će se objekat instancirati pre nego što se neka operacija izvrši sa njim. Druga varijanta je bila da se deklariše slika kao nulabilan objekat na ovaj način:
var slika : ImageView?
Tada bismo morali u kodu za dugme stalno proveravati da li je slika == null. Uopšte, kada god bismo radili sa slikom, morali bismo proveravati da li je null. Rešenje sa lateinit je lepše, jer otklanja taj deo posla.