Layout Editor

Ranije smo videli kako se u XML fajlu može dizajnirati aplikacija. Međutim, ovaj pristup može posle nekog vremena da postane mnogo naporan i težak za praćenje i uređivanje. Iz tog razloga, razvijen je Layout Editor koji omogućava programerima da dizajn aplikacije zadaju vizuelno.
Pretpostavimo, primera radi, da smo napravili novi projekat sa Empty Activity. Kao i ranije, unutar Android Studio, otvorimo naš activity_main.xml fajl, ali ovoga puta ne otvaramo sekciju Code nego Design ili, možda čak i bolje od toga, Split. Prozor bi trebalo da izgleda otprilike ovako:

XML

Dakle, ova aplikacija će sadržati samo jedno polje sa tekstom.
Najpre, možemo u kodu izmeniti da nam glavni layout bude Linear Layout , time brišući i tesktualno polje. Dakle, naš XML fajl će izgledati ovako:

<LinearLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:orientation="vertical"
       tools:context=".MainActivity">

</LinearLayout>

Možemo primetiti da se na ovaj način i sadržaj prozora Design promenio. Ono što uradimo u kodu utiče na prozor Design i obrnuto.
Sada možemo videti kako se na jednostavan način ubacuju elementi. Pozicioniranjem na deo Palette unutar našeg Design prozora, vidimo elemente koje možemo dodati. Tu možemo izabrati TextView i prevući je mišem do dela Component Tree. Kako je Linear Layout ovde glavni layout, onda će se TextView direktno pozicionirati kao dete od LinearLayout.
Sa desne strane Layout Editora, nalazi se spisak atributa objekta koji smo izabrali (selektovali). Spisak atributa je dugačak i mogućnosti su velike. Možemo birati veličinu objekata, menjati njihov tekst, boju pozadine objekta i slično. Za promenu atributa je dovoljno samo kliknuti na polje desno od imena odgovarajućeg atributa i izmeniti ga u zavisnosti od toga kakav je atribut. Recimo, možemo pronaći atribut text i izmeniti tekst našeg TextView. Slično možemo i za veličinu teksta, boju i ostale atribute.
Osim podešavanja atributa i ubacivanja elemenata, Layout Editor omogućava i upravljanje sa niskama uz pomoć fajla strings.xml na elegantan način. Osim toga, sam Layout Editor nas upozorava ukoliko za atribut text koristimo običnu nisku. Da bi se niska smestila u strings.xml i potom upotrebila u našoj aplikaciji, moramo uraditi sledeći niz koraka:

  1. Pored atributa text, kliknuti na tri tačkice
  2. Na prozoru koji se otvori, prosto izaberemo ime niske i njenu vrednost.

Dodavanje dugmeta i njegovo stilizovanje funkcioniše slično kao i kod TextView. Dodavanje slike se malo razlikuje. Kada se slika doda, pojaviće se prozor preko kojeg možemo definisati koji je izvor slike. Odgovarajuću sliku, kao i pre, smeštamo pre toga u odgovarajući direktorijum. Potom ovde izaberemo tu sliku. Pritom, ovime nam se definiše i id naše slike. Ako želimo id da promenimo, dobra je praksa da se koristi Refactor opcija od Android Studio. Sve što treba da uradimo je da kliknemo desni klik našeg miša kod id-a u kodu i izaberemo Refactor->Rename. Na ovaj način će sam Android Studio izmeniti sva pojavljivanja tog id-a.

Interakcija

Layout Editor pruža i niz drugih pogodnosti, osim lakšeg dizajniranja aplikacije. Jedna od takvih pogodnosti je i olakšano i preglednije kontrolisanje ponašanja raznih elemenata. Prikazaćemo na primeru dugmeta kako ovo funkcioniše. Setimo se da smo jedan način kontrolisanja ponašanja dugmeta već videli. Ovaj način zapravo radi istu stvar, ali pruža pregledniji kod lakši za održavanje.
Potrebno je najpre definisati funkciju unutar Kotlin fajla koja obrađuje ponašanje dugmeta kada je ono pritisnuto. Funkcija je ovakve forme:

private fun kadSamKliknut(view: View) {
  naredbe..
}
View je klasa koja je zadužena za upravljanje korisničkim interfejsom. Kao argument funkcije će biti prosleđen onaj objekat klase View na kojem se klik desio. U našem slučaju, proslediće se samo dugme. Primera radi, ako se klikom na dugme ispisuje na određenom TextView tekst "Hello", funkcija može izgledati ovako:
private fun ispisiHello(view: View) {
  val helloText = findViewById<TextView>(R.id.hello)
  helloText.text = "Hello"
  helloText.visibility = View.VISIBLE
}

Da bismo funkciju povezali sa dugmetom, sve što treba da uradimo je da u XML fajlu kod dugmeta dodamo atribut android:onClick.

<Button
  ....
  android:onClick = "ispisiHello"
/>

Android Studio nam omogućava da programiranje ponašanja objekata još olakšamo tako što ćemo isključiti findViewById() metode. Jedna od mana stalne upotrebe findViewById je u tome što se, prilikom svakog klika dugmeta, objekat koji tražimo opet kreira. Rešenje je da se kreira takozvani Binding objekat.
Najpre je potrebno omogućiti opciju dataBinding. Da bi se to uradilo, mora se otići na fajl build.gradle skript u direktorijumu app. Ovaj skript je zadužen za upravljanje bibliotekama koje naša aplikacija koristi. Da ne bi programer sam morao da radi razna povezivanja sa bibliotekama unutar programa, koriste se Gradle skriptovi. Unutar tog fajla lociramo android sekciju i zatim dodajemo unutar nje sledeći kod:

buildFeatures {
    dataBinding true
}

Zatim je potrebno otvoriti XML fajl i uključiti layout tag tako da je on sada roditelj svim elementima. Recimo, ako smo imali LinearLayout u kojem se nalaze neki objekti, XML fajl sada treba da ima ovakvu strukturu:

<layout>
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>

Moramo xmlns atribute prebaciti tako da budu atributi layout taga. Recimo, to bi izgledalo ovako:

<layout xmlns:android = "...">
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>

Nakon što smo to uradili, otvaramo MainActivity.kt i unutar njega dodajemo, iznad onCreate metoda sledeću liniju koda:

private lateinit var binding: ActivityMainBinding

Ako zatraži Android Studio da se uključi odgovarajuća klasa, potrebno ju je uključiti. Promenljivu koju smo deklarisali ćemo sada i da instanciramo. Da bi se to uradilo, mora se prvo obrisati poziv metoda setContentView u metodu setContent, a onda se na njegovom mestu staviti sledeća linija koda:

binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

Ovom linijom koda takođe prikazujemo sadržaj XML fajla na ekranu aplikacije, ali isto tako i povezujemo objekte sa promenljivom binding. Binding objekat se povezuje sa svim elementima koda i instancira svoja polja za svaki od objekata. Ako je objekat Button imao id zec_petar, onda će Binding objekat imati u sebi atribut zecPetar tipa Button koji je povezan sa dugmetom. Sada bi naš kod od ranije izgledao ovako:

private fun ispisiHello(view: View) {
  binding.hello.text = "Hello"
  binding.hello.visibility = View.VISIBLE
}