upoznavanje android korisničkog interfejsa
TRANSCRIPT
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
1/87
Upoznavanje Android korisničkog interfejsa
U drugom poglavlju ste naučili nešto više o Activity klasi i njenom „ životnomciklusu“.
Naučili ste i da aktivnost predstavlja sredstvo za omogućavanje interakcijeizmeđu korisnika i aplikacije.
Međutim, ona, sama po sebi, nema svoju reprezentaciju na ekranu.
Umjesto toga, neophodno je da prikažete sadržaj ekrana korištenjem pogleda igrupa pogleda.
U ovom poglavlju ćete naučiti nešto više o načinu kako se kreira korisnički
interfejs u Android aplikacijama i kako korisnici mogu da interaguju saVašim aplikacijama.
Pored toga, naučit ćete i kako da upravljate promjenama u orijentacijiekrana na Android uređajima.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
2/87
Razumijevanje komponenata ekrana
U drugom poglavlju naučili ste da je osnovna jedinica Android aplikacijeaktivnosti.
Aktivnost omogućava prikazivanje korisničkog interfejsa aplikacije, koja možeda sadrži različite elemente, kao što su tasteri, obilježja, polja za prikazivanjeteksta i slično.
Tipično, definišete svoj korisnički interfejs pomoću odgovarajuće XMLdatoteke( npr. main.xml datoteke, koja je locirana u res/layout folderu Vašeg projekta),koja je sljedećeg oblika:
U toku izvršavanja učitatat ćete korisnički interfejs definisan u XML datoteci pomoću onCretate() metoda rukovaoca u Vašoj Activity klasi, a zatim ćeteiskoristiti setContentView() metod Activity klase:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);}
U toku prevođenja, svaki element u XML datoteci se prevodi u ekvivalentnuAndroid GUI klasu, sa atributima koje definišu metodi.
Nakon toga, Android sistem kreira korisnički interfejs aktivnosti prilikomnjenog učitavanja.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
3/87
Pogledi i grupe pogleda
Određena aktivnost sadrži poglede i grupe pogleda.Pogled je element koji ima svoj prikaz na ekranu.
Elementi pogleda su tasteri, obilježja i polja za prikazivanje teksta.Pogled se izvodi iz bazne klase android.view.View.
Više pogleda se može grupisati u ViewGroup. ViewGroup ( koji i sam predstavlja specijalni tip pogleda) obezbjeđuje da se
pogledi uređuju prema rasporedu i načinu prikazivanja. Primjeri grupa pogleda su : LinearLayout i FrameLayout.
View Group se izvodi iz bazne klase android .view.ViewGroup.
Android podržava sljedeće grupe pogleda: ➤ LinearLayout
➤ AbsoluteLayout
➤ TableLayout
➤ RelativeLayout
➤ FrameLayout
➤ ScrollView
U narednim odjeljcima detaljno su opisane sve grupe pogleda.Obratite pažnju da je u praksi često kombinovanje različitih tipova rasporedaelemenata da bi bio kreiran željeni korisnički interfejs.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
4/87
LinearLayout
LinearLayout uređuje poglede u jednu kolonu ili jednu vrstu.Izvedeni pogledi se mogu uređivai ili vertikalno ili horizontalno.
Da biste vidjeli kako funkcioniše LinearLayout, razmotrite sljedeće elemente,koji se obično nalaze u main.xml datoteci:
U mail.xml datoteci primjetit ćete da je korijeni element i da seu njemu nalazi
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
5/87
Layout_weight i layout_gravity atributi se mogu primjenjivati samo kada je
View ili LinearLayout ili TableLayout.
Širina elementa ispunjava cjelokupnu širinu osnovnog elementa
(koji je u ovom primjeru cijeli ekran) korištenjem fill_parent konstante. Njihova visina je definisana pomoću wrap_content konstante, što znači da jeodređeno visinom sadržaja (u našem primjeru to je tekst koji se prikazuje unjemu).
Ukoliko ne želite da pogled zauzima cijelu vrstu, definišite njihovlayout_width atribut tako da bude wrap_content, kao što je prikazano usljedećem primjeru:
U prethodnom kodu definiše se širina pogleda da bude jednaka širini teksta kojise prikazuje u posmatranom elementu.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
6/87
JEDINICE M JERE
Prilikom definisanja veličine elementa u Android korisničkom interfejsu, treba da vodite računada se koriste sljedeće jedinice mjere:
dp – piksel nezavistan od gustine ( eng. density-independent pixel ) ; jedan dp jeekvivalentan jednom pikselu na ekranu rezolucije 160 dpi ( tačka po inču ).Ovo je preporučena jedinica m jere prilikom specifikacije dimenzije pogleda zaodgovarajući raspored elemenata.Ekran rezolucije 160 dpi definiše osnovnu gustinu ( rezoluciju ) koja se koristi u Android
operativnom sistemu.Možete se koristiti oznake dp ili dip prilikom navođenja piksela koji su nezavisni odgustine.
sp – piksel nezavisan od rezolucije ( eng. scale-independent pixel ).To je identično sa dp, a preporučuje se za definisanje veličine fontova.
pt – tačka, point ( eng. point ).Definisana je kao 1/72 inča, na osnovu fizičke veličineekrana.
px – piksel ( eng. pixel ). Odgovara aktuelnoj veličini piksela na ekranu. Korištenje ove jedinice nije preporučljivo, jer korisnički interfejs neće biti ispravno prikazan nauređajima koji imaju različite rezolucije.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
7/87
Sljedeći korak je definisanje širineTextView i Button pogleda, što se izvršavakorištenjem apsolutne vrijednosti.
U našem primjeru širina za TextViewdefinisana je na 100, a Button 160 dp. Prije
nego što vidite kako će ovako definisani pogledi izgledati na različitim ekranima sarazličitim gustinama piksela, veoma jeznačajno da razumijete kako Androidoperativni sistem prepoznaje ekrane
r azličitih veličina i gustina piksela.
Na slici 3-1 prikazan je ekran telefona
Nexus S. Ovaj telefon sadrži ekran veličine4 inča (po dijagonali), a širina ekrana je2,04 inča. Njegova rezolucija je 480(širina) x 800 (visina) piksela. Slika 3-1
Sa 480 piksela koji su raspoređeni po širini od 2,04 inča, dobija se gustina piksela od oko 235 tačaka po inču (eng. dots per inch, skraćeno dpi).
Kao što vidite na osnovu slike, gustina piksela ekrana zavisi od veličine ekrana i
rezolucije.Android operativni sistem definiše i prepoznaje sljedeće četiri gustine ekrana(gustine tačaka na ekranu):
low density (ldpi) – 120 dpi medium density (mdpi) – 160 dpi high density (hdpi) – 240 dpi extra high density (xhdpi) – 320 dpi
Vaš uređaj će pripadati nekoj od grupa koje su navedene u prethodnoj listi. Nexus S se tretira kao hdpi uređaj, jer je njegova gustina piksela bliža 240 dpi.Međutim HTC Hero sadrži ekran veličine 3,2 inča (po dijagonali), odnosnorezoluciju 320x480 piksela. Njegova gustina piksela je oko 180 dpi. Zbog toga
se on smatra mdpi uređajem, jer je njegova gustina piksela bliža vrijednosti od160 dpi.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
8/87
Da biste provjerili kako će pogledi koji su definisani u XML datoteci izgledati prilikom prikazivanja na ekranima različitih gustina, kreirajte dva AVD uređajasa različitim rezolucijama ekrana i zamišljenim LCD gustinama.
Na slici 3-2 prikazan je AVD uređaj sa rezolucijom 480x800 i LCD gustinom235, što emulira Nexus S.
Na slici 3-3 prikazan je drugi AVD uređa j, sa rezolucijom od 320x480 piksela iLCD gustinom 180, što emulira HTC Hero.
Slika 3-2 Slika 3-3
Na slici 3-4 prikazani su pogledi prilikom emulacije na ekranu gustine 235 dpi.
Na slici 3-5 prikazani su pogledi prilikom emulacije na ekranu gustine 180 dpi.
Slika 3-4 Slika 3-5
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
9/87
Korištenjem dp jedinice omogućava da se pogledi uvijek definišu uodgovarajućom razmjeri, nezavisno od gustine tačaka na ekranu – Androidoperativni sistem automatski skalira veličinu pogleda na osnovu gustine tačakana ekranu.
Uzmimo Button kao primjer ; ukoliko se ovaj element prikazuje na 180 dpiekranu (180 dpi ekran se istovjetno kao i 160 dpi ekran) njegova širina ćeiznositi 160 piksela.
Međutim, ukoliko se ovaj element prikazuje na 235 dpi ekranu (koji se tretirakao 240 dpi ekran) tada če širina biti 240 piksela.
NAČIN KONVERTOVANJA DP U PX
Formula za konvertovanje dp jedinica u px jedinice (piksele) je sljedećeg oblika:Trenutni pikseli = dp*(dpi/160), gdje dpi ima vrijednost 120, 160, 240 ili 320.
Zbog toga, kada je riječ o Button elementu i 235 dpi ekranu, njegova prava širina je 160.
*(240/160) = 240 px. Prilikom prikazivanja na 180 dpi emulator (koji e tretira kao 160 dpi
uređaj), njegova prava veličina u pikselima iznosi 160* (160/160) = 160 px.U ovom primjeru jedan dp je ekvivalentan jednom pikselu.
Da biste potvrdili da je ovo zaista tačno, možete da iskoristite getWidth() metod View objekta i
da odredite širinu u pikselima:
public void onClick(View view) {
Toast.makeText(this,
String.valueOf(view.getWidth()),Toast.LENGTH_LONG).show();
}
Šta bi se dogodilo da, umjesto dp, definišete veličinu korištenjem piksela ( px ) ?
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
10/87
Na slici 3-6 prikazano je kako Label i Button elementi izgledaju na 235 dpi
ekranu.
Na slici 3-7 vide se isti elementi, ali na 180 dpi ekranu.
U ovom primjeru Android operativni sistem ne izvršava nikakvu konverziju,
pošto su sve veličine izražene u pikselima. Uopšteno ( kada je riječ o ekranima jednake veličine), ukoliko za definisanje
pogleda primjenjujete piksele, prikaz će biti manje na uređaju sa većomvrijednošću dpi ekrana, u odnosu na uređaje sa manjoj vrijednošću dpi ekrana.
U prethodnom primjeru navedeno je i da je orijentacija ekrana vertikalna:
Slika 3-6 Slika 3-7
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
11/87
Podrazumijevana orijentacija je horizontalna, pa ukoliko izostavite
android:orientation atribut prikaz će biti kao na slici 3-8.
Slika 3-8
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
12/87
U LinearLayout načinu prikaza možete da primjenite layout_weight ilayout_gravity atribute za definisanje pogleda, kao što je prikazano u sljedećojmodifikovanoj main.xml datoteci:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
13/87
Na slici 3-9 prikazan je položaj za prikazivanje različitih podataka, kao i visina prikaza.
Atribut layout_gravity ukazuje na pozicije kojima treba da teže elementi koji se prikazuju, dok atribut layout_weight specificira raspodjelu raspoloživog
prostora.U primjeru tri tastera zauzimaju oko 16,6 % (1/(1+2+3)*100),
33,3% (2/(1+2+3)*100) i 50 % (3/(1+2+3)*100) raspoloživog po visini,respektivno.
Slika 3-9
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
14/87
Ukoliko promijenite orijentaciju za LinearLayout raspored elemenat da bude
horizontalna, neophodno je da promijenite širinu svakog elementa, tako da bude0 dp da bi raspored elemenata bio onakav kakav je prikazan na slici 3-10:
Slika 3-10
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
15/87
Apsolute Layout
ApsoluteLayout omogućava da specificirate tačnu lokaciju izvedenih elemenata. Razmotrimo sljedeći korisnički interfejs, koji je definisan u main.xml datoteci:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
16/87
Na slici 3-11 prikazana su dva Button pogleda ( testirana na 180 dpi AVD
uređaju), koja su locirana na navedenim pozicijama korištenjemandroid_layout_x i android_layout_y atributa.
Međutim, postoji određeni problem kada se primjenjuje AbsoluteLayout, aodnosi se na aktivnost koja se prikazuje na ekranu sa visokom rezolucijom
( slika 3-12).
Z bog toga se AbsoluteLayout više ne koristi od Android 1.5 verzije operativnogsistema ( iako postoji podrška i u najnovijoj verziji). Treba da izbjegavate da ga primjenjujete u svom korisničkom interfejsu, jernema garancije da će postojati podrška u budućim verzijama Androidoperativnog sistema.
Umjesto toga, neophodno je da primjenjujete drugačije rasporede elemenata,koji su prikazani u ovom poglavlju.
Slika 3-11 Slika 3-12
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
17/87
TableLayout
TableLayout grupiše elemente u vrste i kolone. Možete da koristite element da biste označili vrstu u posmatranojtabeli.
Svaka vrsta može da sadrži jedan ili više pogleda. Svaki pogled koji definišete u određenoj vrsti formira ćeliju.Širina svake kolone određena je najvećom širinom svake ćeliji u posmatranojkoloni.
Razmotrimo sadržaj sljedeće main.xml datoreke:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
18/87
android:text=”Remember Password” />
Na slici 3-13 možete vidjeti kako izgleda prethodno definisan korisničkiinterfejs u Android emulatoru.
Obratite pažnju da u prethodnom primjeru postoje dvije kolone i četiri vrsteTableLayout rasporedu elemenata.
Ćelija koja se nalazi neposredno ispod Password TextView elementa sadži prazan element.
Da niste ovako definisali korisnički interfejs, Remember Password polje za potvrdu bi bilo prikazano ispod Password TextView elementa, kao što je prikazano na slici 3-14.
Slika 3-13 Slika 3-14
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
19/87
RelativeLayout
RelativeLayout raspored omogućava da specificirate način na koji se izvedenielementi prikazuju u odnosu na osnovne elemente.
Razmotrimo sljedeću main.xml datoteku:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
20/87
Obratite pažnje da svaki pogled kojidefinisan RelativeLayout rasporedom
elemenata sadrži atribute kojiomogućavaju definisanje uređen je
jednog elementa u odnosu na drugi.
Možete koristite sljedeće atribute:
➤ layout_alignParentTop
➤ layout_alignParentLeft
➤ layout_alignLeft
➤ layout_alignRight
➤ layout_below
➤ layout_centerHorizontal
Slika 3-15
Vrijednost svakog od navedenih atributa predstavlja identifikator za pogled koji
refencirate.
U prethodnom XML kodu definisan je korisnički intefejs čiji je izgled prikazanna slici 3-15.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
21/87
FrameLayout
FrameLayout raspored elemenata možete da koristite za prikazivanje jednog pogleda.
Pogledi koje dodajete u FrameLayout se uvijek postavljaju u odnosu na gornji
lijevi ugao rasporeda.
Razmotrimo sadržaj sljedeće main.xml datoteke:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
22/87
U ovom primjeru definisan je FrameLayout u RelativeLayout rasporedu
elemenata.
U FrameLayout rasporedu elemenata ugrađen je ImageView. Korisnički interfejs je prikazan na slici 3-16.
Slika 3-16
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
23/87
Ukoliko definišete još jedan pogled ( kao što j e Button) u FrameLayoutrasporedu elemenata, prikaz će se preklapati sa prikazom elemenata definisanihu prethodnom pogledu ( slika 3-17) :
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
24/87
Slika 3-17
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
25/87
ScrollView
ScrollView je specijalni tip FrameLayout prikaza.
On omogućava korisnicima da pristupaju različitim pogledima u listi pogleda,koji zauzmimaju više prostora, nego što to omogućava fizički displej. ScrollView može da sadrži samo jedan izvedeni pogled ili ViewGroup, koji jeobično, LinearLayout tipa.
Sadržaj sljedeće main.xml datoteke prikazuje ScrollView koji sadržiLinearLayout , u kome se prikazuju Button i EditText:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
26/87
Ukoliko učitate prethodni kod u Androdi emulatoru, bit će prikazan korisničkiinterfejs sa slike 3-18.
Slika 3-18
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
27/87
Pošto EditText automatski dobija folus, ispunjava cjelokupni prostor koji jedefinisan za aktivnost ( pošto je njegova visina postavljena na 600 dp).Da biste spriječili postavljanje u fokus, neophodno je da dodate sljedeća dvaatributa u element:
Sada ćete moći da vidite tastere i da skrolujete kroz listu pogleda ( slika 3-19).
Slika 3-19
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
28/87
U nekim situacijama ćete možda željeti da EditText bude automatski u fokusu,ali da se ne prikazuje soft ulazni panel (tastatura) automatski (što se dešava urealnom uređaju). Da biste spri ječili da se prikaže tastatura dodajte sljedeći atribut u
element definisan u AndroidManifest.xml datoteci:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
29/87
PRILAGOĐAVANJA PRIKAZA ORIJENTACIJI UREĐAJA
Jedna od ključnih funkcija savremenih pametnih telefona je njihova mogućnostda ekran mijenja orijentaciju, što je karakteristika Android operativnih sistema.
Ovaj operativni sistem podržava dvije orijentacije ekrana: uspravan (portrait) ihorizontalan (landscape).
Na osnovu inicijalnih podešavanja, prilikom promjene orijentacije ekranAndroid uređaja, ponovo se iscrtava trenutna aktivnost koja se prikazuje, alitako da se sadržaj prikazuje u novoj orijentaciji. Ovo omogućava onCreate () metod aktivnosti, koji se izvršava svaki put kada se
promijeni orijentacija prikaza.
Međutim, prilikom ponovnog prikazivanja pogleda, ponovo se iscrtavajuelementi na svojih originalnim lokacijama (zavisno od rasporeda elemenata koji je pri tome selektovan).
Na slici 3-20 prikazan je jedan od prethodnih primjera, i to u portrait i landscape
režimu.
Obratite pažnju da u landscape režimu postoji dosta slobodnog prostora nadesnoj strani ekrana, koji se može iskoristiti.Bilo koji pogled definisan u donjem dijelu ekrana može da bude sakriven kada
se koristi landscape orijentacija.
Slika 3-20
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
30/87
Možete da primjenjuje dvije tehnike za rukovanje promjenama orijentacijeekrana:
anchoring – najjednostavniji način je učvršćivanje prikaza za četiri iviceekrana.
Prilikom promjene orijentacije ekrana, prikaz elemenata se urednouređuje u odnosu na ivice ekrana.
resizing and repositioning – za razliku od učvršćivanja i centralizovanja,kao jednostavnih tehnika za obezbjeđivanje promjena prikaza elemenata u
pogledima na osnovu promjene orijentacije ekrana, napredna tehnika je
promjena veličine svakog pojednačnog pr ikaza elementa shodno trenutnojorijentaciji ekrana.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
31/87
Učvršćivanje prikaza
Učvršćivanje prikaza može se jednostavno postići korištenjem RelativeLayoutrasporeda.
Razmotrite sljedeću main.xml datoteku, koja sadrži pet Button pogledaugrađenih u element:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
32/87
Obratite pažnju na sljedeće atribute koji se nalaze u različitim Button pogledima:
layout_alignParentLeft – uređuje pogled u odnosu na lijevu stranuosnovnog pogleda
layout_alignParentRight – uređuje pogled u odnosu na desnu stranuosnovnog pogleda
layout_alignParentTop – uređuje pogled u odnosu na gornji dio osnovnog pogleda
layout_alignParentBottom – uređuje pogled u odnosu na donji dio
osnovnog pogleda
layout_centerVertical – centrira se pogled po vertikali u odnosu naosnovni pogled
layout_centerHorizontal – centrira s pogled po horizontali u odnosu naosnovni pogled
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
33/87
Na slici 3-21 predstavljena je aktivnost prilikom prikaza u portrait režimu.
Slika 3-21
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
34/87
Prilikom promjene orijentacije ekrana tako da bude u landscape režimu, četiritastera su uređena u odnosu na četiri ivice ekrana, a centralni taster na središtuekrana proširen je, tako da prikazuje preko cijelog ekrana (slika 3-22).
Slika 3-22
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
35/87
Promjena veličine i položaja
Pored učvršćivanja prikaza za četiri ivice ekrana, postoji i jednostavniji način za podešavanje korisničkog interfejsa na osnovu orijentacije ekrana, a to je
kreiranje posebnog res/layout foldera koji sadrži XML datoteke za korisničkiinterfejs za svaku pojedinačnu orijentaciju.
Da biste podržali landscape režim, možete a kreirate novi folder u res folderu ida mu date naziv layout-land (što predstavlja skraćenicu od landscape).
Na slici 3-23 prikazan je novi folder koji sadrži main.xml datoteku.
U suštini, main.xml datoteka koja se nalazi u layout folderu definiše korisničkiinterfejs za aktivnost u portraid režimu, dok main.xml datoteka u layout-landfolderu definiše korisnički interfejs u landscape režimu.
Slika 3-23
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
36/87
Sljedeći kod predstavlja sadržaj koja se nalazi u layout folderu:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
37/87
android:layout_centerVertical=”true” android:layout_centerHorizontal=”true” />
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
38/87
Sljedeći kod predstavlja sadržaje main.xml datoteke u layout-land folderu(naredbe prikazane podebljanim slovima su dodatni pogledi definisani u
landscape režimu):
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
39/87
android:layout_height=”wrap_content” android:text=”Middle” android:layout_centerVertical=”true” android:layout_centerHorizontal=”true” />
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
40/87
Kada se aktivnost učita u portrait režimu prikazuju se četiri tastera, kao štomožete vidjeti na slici 3-24.
Slika 3-24
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
41/87
Kada se aktivnost učita u landscape režimu, prikazuje se sedam tastera(slika 3-25), što pokazuje da su učitani drugi XML dokumenti prilikom
postavljanja uređaja u različitoj orijentaciji.
Slika 3-25
Primjenjujući ovaj metod, prilikom promjene orijentacije uređaja Androidoperativni sistem automatski učitava odgovarajuću XML datoteku za vašuaktivnost zavisno od trenutne orijentacije ekrana.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
42/87
UPRAVLJANJE PROMJENAMA ORIJENTACIJE EKRANA
Nakon što ste saznali kako se implementiraju dvije tehnike za adaptiranje prikaza na ekranu nakon promjene orijentacije uređaja, razmotrimo sada šta se
događa sa stanjem aktivnosti prilikom promjene orijentacije.
U sljedećoj vježbi demonstrirano je stanje aktivnosti prilikom promjeneorijentacije uređaja.
Datoteka sa kodom Orientations.zip može se preuzeti sa adrese Wrox.com
1. Koristeći Eclipse integrisano razvojno okruženje, kreirajte novi Android
projekat i nazovite ga Orientations.
2. U main.xml datoteku dodajte sljedeće naredbe, prikazane podebljanimslovima:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
43/87
3. U OrientationsActivitiy.java datoteku dodajte sljedeće naredbe prikazane podebljanim slovima:
package net.learn2develop.Orientations;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class OrientationsActivity extends Activity {
/**Izvršava se prilikom prvog definisanja aktivnosti */@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(“StateInfo”, “onCreate”); }
@Override
public void onStart() {
Log.d(“StateInfo”, “onStart”); super.onStart();
}@Override
public void onResume() {
Log.d(“StateInfo”, “onResume”); super.onResume();
}
@Override
public void onPause() {
Log.d(“StateInfo”, “onPause”); super.onPause();
}
@Override
public void onStop() {
Log.d(“StateInfo”, “onStop”); super.onStop();
}
@Override
public void onDestroy() {Log.d(“StateInfo”, “onDestroy”);
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
44/87
super.onDestroy();
}
@Override
public void onRestart() {
Log.d(“StateInfo”, “onRestart”); super.onRestart();
}
4.
Pritisnite F11 tipku da biste debagovali aplikaciju u Android emulatoru.
5. Unesite određeni tekst u dva EditText pogleda ( slika 3-26).
Slika 3-26
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
45/87
6.
Promijenite orijentaciju uređaja u Android emulatoru pristiskom Ctrl+F11kombinacije tipki. Na slici3-27 je emulator u landscape režimu. Obratite pažnju da je prvi EditText pogled i dalje vidjljiv, ali da je drugiEditText pogled prazan.
Slika 3-27
7. Pratite ono što se prikazuje prilikom izvršavanja u LogCat prozoru( neophodno je da pređete u Debug način prikaza u eclipse integrisanomrazvojnom okruženju). Trebalo bi da vidite sljedeći tekst:
12-15 12:27:20.747: D/StateInfo(557): onCreate12-15 12:27:20.747: D/StateInfo(557): onStart
12-15 12:27:20.747: D/StateInfo(557): onResume
...
12-15 12:39:37.846: D/StateInfo(557): onPause
12-15 12:39:37.846: D/StateInfo(557): onStop
12-15 12:39:37.866: D/StateInfo(557): onDestroy
12-15 12:39:38.206: D/StateInfo(557): onCreate
12-15 12:39:38.216: D/StateInfo(557): onStart
12-15 12:39:38.257: D/StateInfo(557): onResume
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
46/87
Način funkcionisanja
Na osnovu rezultata koji su prikazani u LogCat prozoru, očigledno je da seaktivnost uklanja kada uređaj mijenja orijentaciju:
12-15 12:39:37.846: D/StateInfo(557): onPause
12-15 12:39:37.846: D/StateInfo(557): onStop
12-15 12:39:37.866: D/StateInfo(557): onDestroy
Aktivnost se nakon toga, ponovo kreira:
12-15 12:39:38.206: D/StateInfo(557): onCreate
12-15 12:39:38.216: D/StateInfo(557): onStart12-15 12:39:38.257: D/StateInfo(557): onResume
Veoma je značajno da razumijete ovo funkcionisanje, zato što je neophodno daizvršite dodatne korake da biste sačuvali stanje Vaše aktivnosti prije nego što se
promijeni orijentacija uređaja.Vaša aktivnost može da ima određene promjenjive koje sadrže vrijednostneophodne za dodatna izračunavanja u toj aktivnosti.Treba da sačuvate stanje svake aktivnosti pomoću onPause () metoda, koje se
izvršava uvijek kada se u toku izvršavanja određene aktivnosti mijenjaorijentacija uređaja. U sljedećem dijelu predstavljena su dva načina za snimanje ovih informacija ostanju.
Još jedno značajno ponašanje aplikacije koje treba da razumijete je da su samo pogledi kojima su definisani nazivi (pomoću android:id atributa) u određenojaktivnosti sa perzistentnim stanjem nakon uklanjanja aktivnosti.
Korisnik može da promijeni orijentaciju prilikom unosa odgovarajućeg teksta uEditText polje.
Kada se to dogodi, bilo koji tekst koji je unijet u EditText polje bit će perzistentan i automatski će se restaurirati nakon ponovnog iniciranja oveaktivnosti.
Obratno: ukoliko ne definišete naziv EditText pogleda navođenjem android:idatributa, aktivnost neće moći da sačuva tekst koji je korisnik prije promjeneorijentacije uređaja unio u odgovarajuće polje.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
47/87
Čuvanje informacija o stanju u toku promjena konfiguracije
Do sada ste naučili da se prilikom promjene orijentacije ekrana prekidaaktivnost, a zatim ponovo inicira.
Vodite računa da prilikom ponovnog iniciranja aktivnost trenutnog stanja može biti uklonjeno.
Prilikom uklanjanja aktivnosti, inicira se jedan od navedenih metoda ili oba:
onPause () ovaj metod se inicira uvijek kada se aktivnost ukloni ili
proslijedi u pozadinu.
onSaveInstanceState () ovaj metod može također da se inicira kada
aktivnost treba da bude uklonjena ili postavljena u pozadinu, kao ionPause () metod.
Međutim, za razliku od onPause () metoda, onSaveInstanceState () se neinicira kada se aktivnost ukloni sa steka (što se javlja ako korisnik pritisne
back taster) zato što ne postoji potreba za kasnijim restauriranjem stanjaaktivnosti.
Da biste sačuvali stanje određene aktivnosti, možete uvijek da implementirateonPause () metod, a zatim da koristite sopstvene načine za čuvanje stanja
aktivnosti, kao što su korištenje baze podataka, interne ili eksterne datoteke islično.
Ukoliko jednostavno želite da sačuvate stanje određene aktivnosti, tako da seona može kasnije restaurirati prilikom njuenog ponovnog iniciranja (što sedogađa prilikom promjene orijentacije uređaja) mnogo jednostavniji način jeimplementiranje onSaveInstanceState () metoda, pošto on omogućava korištenjeBundle objekta kao argumenta, koji možete da kopristite da biste snimili stannje
Vaše aktivnosti.
U sljedećem kodu prikazano je kako možete da snimite string ID u Bundleobjekat u toku izvršavanja onSaveInstanceState () metoda:
@Override
public void onSaveInstanceState(Bundle outState) {
//---snimanje svega što želite da sačuvate---outState.putString(“ID”, “1234567890”);
super.onSaveInstanceState(outState);}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
48/87
Nakon što se aktivnost ponovo inicira, prvo se izvršava onCreate () metod, anakon njega onRestoreInstanceState () metod, koji omogućava da očitate stan jekoje ste prethodno snimili korištenjem onSaveInstanceState () metoda pomoćuBundle objekta kao argumenta:
@ Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//---očitavanje prethodno sačuvanih informacija---String ID = savedInstanceState.getString(“ID”);
}
Iako možete da koristite onSaveInstanceState () metod za snimanje informacija,obratite pažnju da mogu da se snime samo informacije o stanju u odgovarajućemBundle objektu .
Ukoliko je neophodno da snimite više složenih struktura podataka, ovo nijeodgovarajuće rješenje za Vas.
Još jedan metod koji možete koristiti je onRetainNonConfigurationInstance ().On se inicira kada aktivnost treba da se ukloni usljed konfiguracijskih promjena
(kao što su promjena orijentacije ekrana, raspoloživost tastature i slično).
Podatke o trenutnom stanju možete da snimite pomoću ovog metoda na sljedećinačin:
@Override
public Object onRetainNonConfigurationInstance() {
//---snimite ovdje šta god želite;koristi se Objects tip---return(“Some text to preserve”);
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
49/87
Obratite pažnju da ovaj metod vraća Object tip, koji omogućava da snimiteskoro svaki drugi tip podataka.
Snimljeni tip podataka možete da ekstrahujete u onCreate () metodu, koristećigetLastNonConfigurationInstance () metod:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(“StateInfo”, “onCreate”); String str = (String) getLastNonConfigurationInstance();
}
Metodi onRetainNonConfigurationInstance () i getLastNonConfiguratioInstance
() se koriste kada je neophodno momentalno sačuvati određene podatke, kaonaprimjer, prilikom preuzimanja određenih podataka sa web servisa i pr omjeneorijentacije ekrana.
U ovom scenariju snimanje podataka korištenjem dva prethodno navedenametoda je mnogo efikasnija, nego ponovo preuzimanje podataka.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
50/87
Detektovanje promjene orijentacije
Nekada je neophodno da znate trenutnu orijentaciju uređa ja u toku izvršavanjaaplikacije, da biste je utvrdili, možete da koristite WindowsManager klasu.
U sljedećem primjeru prikazano je kako se programski detektuje trenutnaorijentacija koja se odnosi na aktivnost:
import android.view.Display;
import android.view.WindowManager;
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//---očitavanje trenutnih informacija o prikazu---WindowManager wm = getWindowManager();
Display d = wm.getDefaultDisplay();
if (d.getWidth() > d.getHeight()) {
//---landscape mode---Log.d(“Orientation”, “Landscape mode”);
}
else {
//---portrait mode---
Log.d(“Orientation”, “Portrait mode”); }
}
Metod getDefaultDisplay () vraća Display objekat koji predstavlja ekranuređaja. Možete da očitate njegovu širinu i visinu, odnosno trenutno orijentaciju.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
51/87
Kontrola orijentacije u aktivnosti
U određenim situacijama je neophodno da obezbjedite da se aplikacija izvršavasamo u određenoj orijentaciji ekrana uređaja.
Možda ćete pisati igru koja treba da se pregleda samo u landscape režimu.U ovoj situaciji možete programski da spriječite promjenu orijentacijekorištenjem setRequestOrientation () metoda Activity klase:
import android.content.pm.ActivityInfo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//--- promjena u landscape režim---setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_
LANDSCAPE);
}
Da biste promijenili orijentaciju da bude u portrait režimu, upotrijebite
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT konstantu.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
52/87
Pored setRequestOrientation () metoda možete da koristite i atributandroid:screenOrientation elementa u AndroidManifest.xml datoteci
(kao što je prikazano u sljedećem primjeru) da biste ograničili da se aktivnostizvršava u određenoj orijentaciji ekrana uređaja:
U prethodnom primjeru ograničena je aktivnost samo na jednoj orijentaciji(landscape režim) i spriječeno je da se aktivnost ukloni ; to znači da aktivnostneće biti uklonjena i da onCreate () metod neće biti ponovo iniciran nakon
promjene orijentacije uređaja.
Postoje još dvije dodatne vrijednosti koje možete da specificirate uandroid:screenOrientation atributu:
portrait – portrait režim sensor – zasnovan na akcelerometru (default vrijednost)
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
53/87
KORIŠTENJE LINIJE AKCIJA
Pored fragmenata, još jedna nova funkcija koja je uvedena u Android 3 i 4 jeAction Bar.
Umjesto tradicionalne naslovne linije, koja je locirana u gornjem dijelu ekrana
uređaja, Action Bar prikazuje ikonu aplikacije i naslov aktivnosti. Opciono, desno od Action Bar linije nalaze se Action stavke.
Na slici 3-28 prikazana je ugrađena Email aplikacija, kod koje se prikazujeikona aplikacije, naziv aktivnosti određene akcione stavke u liniji akcija.U narednom dijelu detaljnije su opisane akcione stavke.
Slika 3-28
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
54/87
U sljedećoj vježbi prikazano je kako da programski skrivate ili prikazujeteAction Bar.
1. U Eclipse integrisanom razvojnom okruženju kreirajte novi Android
projekat i dajte mu naziv MyActionBar.
2. Pritisnite F11 taster da biste debagovali aplikaciju na Android emulatoru.
Treba da vidite aplikaciju i njen Action Bar, koji je lociran u gornjem
dijelu ekrana (sadrži ikonu aplikacije i naziv aplikacije, slik a 3-29).
Slika 3-29
3.
Da biste sakrili Action Bar, neophodno je da u AndroidManifest.xml
datoteku dodate sljedeće linije koje su prikazane podebljanim slovima:
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
55/87
4. Označite naziv projekta u Eclipse integrisanom razvojnom okruženju, azato, pritisnite F11 taster, da biste ponovo debagovali aplikaciju u
Android emulatoru. Ovog puta se Action Bar ne prikazuje (slika 3-30).
Slika 3-30
5. Možete i programski ukloniti Action Bar, koristeći ActionBar klasu. Da biste to uradili, neophodno je da prvo uklonite android:theme atribut koji
ste dodali u jednom od prethodnih koraka. To je važno, jer će usuprotnom, sljedeći korak dovesti do pojave izuzetka prilikom izvršavanjaaplikacije.
6. Modifikujte MyActionBarActivity.java datoteku na sljedeći način:
package net.learn2develop.MyActionBar;
import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
public class MyActionBarActivity extends Activity {
/** izvršava se prilikom prvog definisanja aktivnosti. */
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
56/87
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = getActionBar();
actionBar.hide();
//actionBar.show(); //---ponovo se prikazuje---
}
}
7. Pritisnite F11 da biste ponovo debagovali aplikaciju u emulatoru.
Action Bar ostaje i dalje skriven.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
57/87
Način funkcionisanja
Atribut android:theme omogućava da prekinete prikzazivanje linija akcija uVašoj aktivnosti. Ukoliko postavite da ovaj atribut ima vrijednost
@android:style/Theme.Holo.NoActionBar, neće biti prikazivan Action Bar.Alternativno, možete programski da dobijete referencu na Action Bar u tokuizvršavanja korištenjem getActionBar () metoda. Izvršavanje hide () metoda omogućavanje skrivanje linija akcija, dokizvršavanje show() metoda omogućava njeno ponovno prikazivanje.Obratite pažnju da, prilikom korištenja android:theme atributa za sklanjanjelinija akcija, izvršavanje getActionBar () metoda daje null u toku izvršavanja
aplikacije.Zbog toga je uvijek bolje da se Action Bar postavlja/ uklanja programski
korištenjem Action Bar klase.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
58/87
Dodavanje stavki akcija u Action Bar
Pored ikone aplikacije i naziva aktivnosti sa lijeve strane linije akcija, možete da prikazujete i dodatne stavke – one se nazivaju stavke akcija.
Stavke akcija su prečice za određene često izvršavane akcije u aplikaciji. Ukoliko razvijate aplikaciju za čitanje RSS poruka, stavke akcija mogu bitiRefresh feed, Delete feed i Add new feed.
U sljedećoj vježbi prikazano je kako se dodaju stavke akcija u Action Baru.
1.
U MyActionBar projekat koji ste kreirali u prethodnom dijelu u
MyActionBarActivity.java datoteku dodajte sljedeći kod, prikazan
podebljanim slovima:
package net.learn2develop.MyActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MyActionBarActivity extends Activity {
/** izvršava se prilikom prvog definisanja aktivnosti. */@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//ActionBar actionBar = getActionBar();//actionBar.hide();
//actionBar.show(); //---ponovo s prikazuje---
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
59/87
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return MenuChoice(item);
}
private void CreateMenu(Menu menu)
{
MenuItem mnu1 = menu.add(0, 0, 0, “Item 1”); {
mnu1.setIcon(R.drawable.ic_launcher);
mnu1.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_RO
OM);
}
MenuItem mnu2 = menu.add(0, 1, 1, “Item 2”); {
mnu2.setIcon(R.drawable.ic_launcher);
mnu2.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_RO
OM);
}
MenuItem mnu3 = menu.add(0, 2, 2, “Item 3”);
{mnu3.setIcon(R.drawable.ic_launcher);
mnu3.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_RO
OM);
}
MenuItem mnu4 = menu.add(0, 3, 3, “Item 4”); {
mnu4.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_RO
OM);
}
MenuItem mnu5 = menu.add(0, 4, 4, “Item 5”); {
mnu5.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_RO
OM);
}
}
private boolean MenuChoice(MenuItem item)
{switch (item.getItemId()) {
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
60/87
case 0:
Toast.makeText(this, “You clicked on Item 1”, Toast.LENGTH_LONG).show();
return true;
case 1:Toast.makeText(this, “You clicked on Item 2”,
Toast.LENGTH_LONG).show();
return true;
case 2:
Toast.makeText(this, “You clicked on Item 3”, Toast.LENGTH_LONG).show();
return true;
case 3:
Toast.makeText(this, “You clicked on Item 4”, Toast.LENGTH_LONG).show();
return true;
case 4:
Toast.makeText(this, “You clicked on Item 5”, Toast.LENGTH_LONG).show();
return true;
}
return false;}
}
2. Pritisnite F11 taster da biste debagovali aplikaciju u Android emulatoru.
Pratite ikone koje se prikazuju u desnom dijelu linija akcija ( slika 3-31).
Ukoliko kliknete MENU taster u emulatoru, bit će prikazane preostalestavke menija ( slika 3-32).
To je poznato kao overflow meni.
Na uređajima koji nemaju MENU taster overflow meni je prikazan uobliku ikone sa strelicom.
Na slici 3-33 prikazana je ista aplikacija, koja se izvršava na Asus EeePad Transformer računaru ( operativni sistem Android 3.2.1).
Nakon što kliknete overflow meni, prikazuju se ostale stavke menija.
3. Ukoliko kliknete stavku menija, Toast klasa prikazuje naziv označene
stavke menija ( slika 3-34).
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
61/87
Slika 3-31 Slika 3-32
Slika 3-33 Slika 3.34
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
62/87
4.
Pritisnite Control F11 kombinaciju tastera da biste promijenili orijentaciju
ekrana u emulatoru, tako da se primjenjuje landscape režim. Sada se prikazuju stavk e akcija u liniji akcija, kao što je prikazano na slici3-35, pri čemu su tri ikone, a jedna je tekstualna.
Slika 3-35
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
63/87
Način funkcionisanja
U liniji akcija se prikazuju stavke akcija izršavanjem onCreateOptionsMenu ()
metoda aktivnosti:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
U prethodnom primjeru koristi se CreateMenu () metod za prikazivanje listestavki menija:
private void CreateMenu(Menu menu)
{
MenuItem mnu1 = menu.add(0, 0, 0, “Item 1”); {
mnu1.setIcon(R.drawable.ic_launcher);
mnu1.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
MenuItem mnu2 = menu.add(0, 1, 1, “Item 2”); {
mnu2.setIcon(R.drawable.ic_launcher);
mnu2.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
MenuItem mnu3 = menu.add(0, 2, 2, “Item 3”); {
mnu3.setIcon(R.drawable.ic_launcher);
mnu3.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
MenuItem mnu4 = menu.add(0, 3, 3, “Item 4”); {
mnu4.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
MenuItem mnu5 = menu.add(0, 4, 4, “Item 5”); {
mnu5.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
64/87
Da bi kao svaka stavka menija bila prikazana akciona stavka , neophodno je da
izvršite setShowAsAction () metod , uz navođenjeSHOW_AS_ACTION_IF_ROOM konstante.
Tako da definišete da Androdi uređaj prikazuje kao stavku menija akcionu
stavku, pod uslovom da postoji dovoljno prostora za njeno prikazivanje.
Kada korisnik selektuje odgovarajuću stavku menija, izvršava se metodonOptionsItemSelected () :
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return MenuChoice(item);
}
Ovdje pozivate MenuChoice () metod koji ste samostalno definisali da biste
provjerili koja stavka menija je kliknuta, a zatim se prikazuje odgovarajuća poruka:
private boolean MenuChoice(MenuItem item)
{
switch (item.getItemId()) {case 0:
Toast.makeText(this, “You clicked on Item 1”, Toast.LENGTH_LONG).show();
return true;
case 1:
Toast.makeText(this, “You clicked on Item 2”, Toast.LENGTH_LONG).show();
return true;
case 2:
Toast.makeText(this, “You clicked on Item 3”, Toast.LENGTH_LONG).show();
return true;
case 3:
Toast.makeText(this, “You clicked on Item 4”, Toast.LENGTH_LONG).show();
return true;
case 4:Toast.makeText(this, “You clicked on Item 5”,
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
65/87
Toast.LENGTH_LONG).show();
return true;
}
return false;
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
66/87
Podešavanje akcionih stavki i ikona aplikacije
U prethodnom primjeru su stavke menija prikazivane bez dodatnog teksta.
Ukoliko želite da prikazujete i tekst za stavku akcije pored ikone, neophodno jeda koristite “|” operator i MenuItem .SHOW_AS_ACTION_WITH_TEXT Konstantu:
MenuItem mnu1 = menu.add(0, 0, 0, “Item 1”); {
mnu1.setIcon(R.drawable.ic_launcher);
mnu1.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
Ovim kodom se omogućava da se ikona prikazuje zajedno sa tekstomodgovarajuće stavke menija ( slika 3-36).
Slika 3-36
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
67/87
Korisnici mogu da kliknu akcione stavke, ali i ikonu aplikacije u liniji akcija.
Kada korisnik klikne ikonu aplikacije, izvršava se onOptionsItemSelected ()metod.
Da biste identifikovali ikonu aplikacije koja se poziva, neophodno je da
provjerite identifikacioni broj stavke u odnosu na android.R.id.home konstantu:
private boolean MenuChoice(MenuItem item)
{
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this,
“You clicked on the Application icon”, Toast.LENGTH_LONG).show();
return true;
case 0:
Toast.makeText(this, “You clicked on Item 1”, Toast.LENGTH_LONG).show();
return true;
case 1:
//...
}
return false;}
Da biste omogućili da ikoan alikacije može da se klikne, neophodno je daizvršite setDisplayHomeAsUpEnabled ():
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
//actionBar.hide();
//actionBar.show(); //---ponovo se prikazuje---
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
68/87
Na slici 3-37 prikazan je taster u obliku strelice pored ikone aplikacije.
Slika 3-37
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
69/87
Ikona aplikacije se često koristi u aplikacijama da bi se omogućilo korisnicimada se vrate na glavnu aktivnost aplikacije.
Vaša aplikacija može da sadrži više aktivnosti, a Vi možete da koristite njenuikonu kao prečicu koja će korisnicima omogućiti da se vrate direktno na glavnu
aktivnost Vaše aplikacije. Da biste to uradili, pogodno je da kreirate Intent objekat i da ga definišetekorištenjem Intent.FLAG_ACTIVITY_CLEAR_TOP indikatora ( flega):
case android.R.id.home:
Toast.makeText(this,
“You clicked on the Application icon”, Toast.LENGTH_LONG).show();
Intent i = new Intent(this, MyActionBarActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
return true;
Intent.FLAG_ACTIVITY_CLEAR_TOP indikator obezbjeđuje da se ukloni nizaktivnosti koje se nalaze u back steku kada korisnik klikne ikonu aplikacije u
liniji akcija.Zbog toga, ukoliko korisnik klikne back taster, ostale aktivnosti u aplikaciji neće
ponovo biti prikazivane.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
70/87
PROGRAMSKO KREIRANJE KORISNIČKOG INTERFEJSA
Do sada ste korisničke interfejse aplikacija u ovom poglavlju kreiralikorištenjem XML datoteka.
Kao što smo već pominjali, možete da ih kreirate i korištenjem koda. Ovaj pristup je koristan ukoliko korisnički interfejs mora da se dinamičkimijenja utoku izvršavanja aplikacije. Pretpostavimo da kreirate sistem za rezervisanje bioskopskih karata i da Vašaaplikacija treba da prikazuje mjesto u svakom bioskopu i da se koriste određenitasteri.
U ovom primjeru bit će neophodno da dinamički generišete korisnički nterfejs
na osnovu bioskopa kojeg je označio korisnik u određenom trenutku.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
71/87
U sljedećoj vježbi prikazan je kod koji je neophodan da biste mogli dadinamički kreirate korisnički interfejs za određenu aktivnost.
Datoteku sa kodom UICode.zip možete da preuzmete sa adrese Wrox.com
1. U Eclipse integrisanom razvojnom okruženju kreirajte novi Android projekat i dajte mu naziv UICode.
2. U UICodeActivity.java datoteku dodajte sljedeće naredbe, koje su prikazane podebljanim slovima:
package net.learn2develop.UICode;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UICodeActivity extends Activity {
/** izvršava se prilikom prvog definisanja aktivnosti. */@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
//---parametri pogleda---
LayoutParams params =
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
//---definisanje rasporeda elemenata---
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
//---kreiranje textview prikaza---
TextView tv = new TextView(this);
tv.setText(“This is a TextView”); tv.setLayoutParams(params);
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
72/87
//---kreiranje tastera---
Button btn = new Button(this);
btn.setText(“This is a Button”); btn.setLayoutParams(params);
//---dodavanje textview prikaza---
layout.addView(tv);
//---dodavanje tastera---
layout.addView(btn);
//---kreiranje parametara rasporeda elemenata---
LinearLayout.LayoutParams layoutParam =
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT );
this.addContentView(layout, layoutParam);
}
}
3.
Pritisnite F11 taster da biste debagovali aplikaciju u Androdi emulatoru. Na slici 3-38 prikazana je aktivnost koja je definisana prethodnim kodom.
Slika 3-38
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
73/87
Način funkcionisanja
U ovom primjeru prvo se postavlja u komentar setContentView () naredba, tako
da se ne učitava korisnički interfejs koji je definisan u main.xml datoteci.
Nakon toga se kreira LayoutParams objekat, u cilju specificiranja layout
parametra, koji će koristiti drugi pogledi ( njih ćete kasnije definisati):
//---parametri pogleda---
LayoutParams params =
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
Također ste kreirali LinearLayout objekat, koji sadrži sve poglede u Vašojaktivnosti:
//---definisanje rasporeda elemenata---
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
Nakon toga, definisali ste TextView i Button pogled:
//---kreiranje textview prikaza---
TextView tv = new TextView(this);
tv.setText(“This is a TextView”); tv.setLayoutParams(params);
//---kreiranje tastera---
Button btn = new Button(this); btn.setText(“This is a Button”); btn.setLayoutParams(params);
Zatim ste ih dodali u LinearLayout objekat:
//---dodavanje textview prikaza---
layout.addView(tv);
//---dodavanje tastera---layout.addView(btn);
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
74/87
Kreirali ste i LayoutParams objekat, koji će se koristiti u LinearLayout objektu:
//---kreiranje parametara rasporeda elemenata---
LinearLayout.LayoutParams layoutParam =new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT );
Konačno, dobili ste LinearLayout objekat u svoju aktivnost:
this.addContentView(layout, layoutParam);
Kao što možete da vidite, korištenje koda za kreiranje korisničkog interfejsa jezaista težak posao.
Zbog toga, dinamički generišite kod za korisnički interfej samo kada je to zaistaneophodno.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
75/87
PRAĆENJE OBAVJEŠTENJA ZA KORISNIČKI INTERFEJS
Korisnici interaguju sa Vašom aplikacijom korištenjem korisničkog interfejsa u dva nivoa: na nivou aktivosti i na nivou pogleda.
Na nivou aktivnosti Activity klasa sadrži metode koje možete da predefinišeteza svoje potrebe.
Opšte metodi koje možete da predefinišete u Vašim aktivnostima su sljedeće:
➤ onKeyDown — izvršava se kada je pritisnut taster i ne rukuje se ni jednim pogledom u konkretnoj aktivnosti
➤ onKeyUp — izvršava se kada se pusti određeni taster i ne rukuje se ni sa
jednim pogledom u konkretnoj aktivnosti
➤ onMenuItemSelected — izvršava se kada korisnik selektuje stavku menija panela
➤ onMenuOpened — izvršava se kada korisnik otvori meni panela
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
76/87
Predefinisanje metoda definisanih u aktivnosti
Da bismo demonstrirali kako se obavlja interakcija sa aktivnostima, u sljedećem primjeru predefinisani su određeni metodi koji su definisani u baznoj klasiaktivnosti.
Datoteku sa kodom UIActivity.zip možete preuzeti sa Wrox.com
1. U Eclipse integrisanom razvojnom okruženju kreirajte novi Android projekat i dajte mu naziv UIActivity.
2. U main.xml datoteku dodajte sljedeće nared be, koje su prikazane
podebljanim slovima ( zamjenjuju TextView):
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
77/87
3.
U UIActivity. Java datoteku dodajte sljedeće naredbe, koje su prikazane podebljanim slovima:
package net.learn2develop.UIActivity;
import android.app.Activity;
import android.view.KeyEvent; import android.os.Bundle;
import android.widget.Toast;
public class UIActivityActivity extends Activity {
/** izvršava se prilikom prvog definisanja aktivnosti. */@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
Toast.makeText(getBaseContext(),
“Center was clicked”, Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
Toast.makeText(getBaseContext(),
“Left arrow was clicked”, Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
Toast.makeText(getBaseContext(),
“Right arrow was clicked”,
Toast.LENGTH_LONG).show();break;
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
78/87
case KeyEvent.KEYCODE_DPAD_UP:
Toast.makeText(getBaseContext(),
“Up arrow was clicked”, Toast.LENGTH_LONG).show();
break;case KeyEvent.KEYCODE_DPAD_DOWN:
Toast.makeText(getBaseContext(),
“Down arrow was clicked”, Toast.LENGTH_LONG).show();
break;
}
return false;
}
4. Pritisnite F11 taster da biste debagovali aplikaciju u Android emulatoru.
5. Kada se završi učitavanje aktivnosti, unesite određeni tekst u EditText. Nakon toga, kliknite streliicu naniže na direkcionom pedu.Posmatrajte poruku koja se prikazuje na ekranu, kao što je prikazano naslici 3- 39.
Slika 3-39
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
79/87
Način funkcionisanja
Nakon iniciranja aktivnosti, pokazivač će zasvijetliti u EditText polju, jer senalazi u fokusu .
U MainActivity klasi predeinisali ste onKeyDown () metod bazne Activity
klase:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER://...
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
//...
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
//...
break;
case KeyEvent.KEYCODE_DPAD_UP://...
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
//...
break;
}
return false;
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
80/87
U Android operativnom sistemu , kada pritisnete bilo koji taster na svom
uređaju, pogled koji trenutno u fokusu pokušava da rukuje generisanimdogađajem.
U našem primjeru, kada je EditText u fokusu i kada pritisnete taster , edit Text pogled rukuje događajem i prikazuje karak ter koji ste upravo pritisnuli.Međutim, ukoliko pritisnete direkcione tastere ( strelica naviše ili naniže),EditText ogled neće rukovati ovim događajima; umjesto toga, događaj se
prosljeđuje aktivnosti, a zatim se prikazuje poruka koja ukazuje koji je taster pritisnt.
Obratite pažnnju da je fokus i sada prosljeđen na sljedeći pogled, koji se odnosina OK taster.
Ukoliko EditText pogled već sadrži određeni tekst i pokazivač je na krajuunijetog teksta, pritiskanjem strelice se ne inicira onKeyDown () metod;
jednostavno se pomijera pokazivač jednom mjesto ulijevo. Razlog je činjenica da je EditText pogled, već rukovao tim događajem. Ukoliko, umjesto toga, pritisnete desnu strelicu
( kada se pokazivač nalazi na kraju teksta), izvršava se onKeyDown() metod( pošto u tom slučaju EditText pogled ne rukuje ovim događajem). Isto važi i za situaciju u kojoj se pokazivač nalazi na početku EditText polja.
Ukoliko, kliknere lijevu strelicu, inicira se izvršavanje onKeyDown () metoda, aukoliko kliknete desnu strelicu, jednostavno se pomijera pokazivač za jedankarakter udesno.
Kada je OK taster u fokusu, pritisnete centralni taster na direkcionom pedu.
Obratite pažnju da se ne prikazuje poruka Cener was clicked. Razlog toga je činjenica da Button pogled sam ne rukuje događajem koji seodnosi na pritiskanjem tastera.
Zbog toga, onKeyDown () metod nije identifikovao odogađaj.
Obratite pažnju da onKeyDown () metod vraća logičku ( bulovu) vrijednost kaorezultat izvršavanja. Treba da se vrati vrijednost true ukoliko želite da ukažete sistemu da ste završilirazmatranje događaja, odnosno da sistem ne mora da nastavi obradu.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
81/87
Razmorimo sljedeću situaciju u kojoj se vraća vrijednost true nakonidentifikovanja svakog pojedinačnog tastera:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
Toast.makeText(getBaseContext(),
“Center was clicked”, Toast.LENGTH_LONG).show();
//break;
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
Toast.makeText(getBaseContext(),
“Left arrow was clicked”, Toast.LENGTH_LONG).show();
//break;
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
Toast.makeText(getBaseContext(),“Right arrow was clicked”, Toast.LENGTH_LONG).show();
//break;
return true;
case KeyEvent.KEYCODE_DPAD_UP:
Toast.makeText(getBaseContext(),
“Up arrow was clicked”, Toast.LENGTH_LONG).show();
//break;
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
Toast.makeText(getBaseContext(),
“Down arrow was clicked”, Toast.LENGTH_LONG).show();
//break;
return true;}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
82/87
return false;
}
Ukoliko isprobate ovaj kod, utvrdit ćete da ne možete da obavljate navigaciju
između pogleda korištenja tastera sa strelicama.
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
83/87
Registrovanje događaja za poglede
Pogledi mogu da iniciraju događaje prilikom interakcije sa korisnicima. Kada korisnik pritisne određeni taster, neophodno je da se rukuje događajem dase izvrši odgovarajuća akcija. Da biste to uradili, eksplicitno registrujte događaje na pojedinačne poglede.
Koristeći isti primjer koji smo razmatrali u prethodnom dijelu, recimo da su zaaktivnost definisana dva Button pogleda; zbog toga , možete da registrujetedogađaje koji se odnose na pritiskanje tastera korištenjem anonimne klase, kaošto je prikazano u sljedećem kodu:
package net.learn2develop.UIActivity;import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class UIActivityActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//---dva tastera su povezana za jednog istog rukovaoca
događajima---Button btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(btnListener);
Button btn2 = (Button)findViewById(R.id.btn2);
btn2.setOnClickListener(btnListener);
}
//---kreirajte anonimne klase za identifikovanje pritiskanja tastera---
private OnClickListener btnListener = new OnClickListener()
{
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
84/87
public void onClick(View v)
{
Toast.makeText(getBaseContext(),
((Button) v).getText() + “ was clicked”,
Toast.LENGTH_LONG).show();}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//...
}
}
Ukoliko sada kliknete OK ili Cancel taster, prikazuje se odgovarajuća poruka( slika 3-40), objezbjeđujući da se događaj ispravno poveže sa odgovarajućimkodom.
Slika 3-40
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
85/87
Pored anonimne klase za rukovaoca događaja, možete da definišete i anonimnuunutrašnju klasu za rukovanje događajima.
U sljedećem primjeru prikazano je kako možete da koristite onFocusChange()
metod za EditText pogled:
import android.widget.EditText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//---dva tastera su povezana za jednog istog rukovaoca događajima---
Button btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(btnListener);
Button btn2 = (Button)findViewById(R.id.btn2);
btn2.setOnClickListener(btnListener);
//---kreiranje anonimne unutrašn je klase koja identifikuje fokus---EditText txt1 = (EditText)findViewById(R.id.txt1);
txt1.setOnFocusChangeListener(new
View.OnFocusChangeListener()
{
@Override
public void onFocusChange(View v, boolean hasFocus) {
Toast.makeText(getBaseContext(),
((EditText) v).getId() + “ has focus - “ +hasFocus,
Toast.LENGTH_LONG).show();
}
});
}
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
86/87
-
8/15/2019 Upoznavanje Android Korisničkog Interfejsa
87/87
Rukovalac click događajem za dva tastera se mora napisati na sljedeći način( korištenjem anonimne unutrašnje klase) :
//---the two buttons are wired to the same event handler---
Button btn1 = (Button)findViewById(R.id.btn1);//btn1.setOnClickListener(btnListener);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//---uraditi nešto---}
});
Button btn2 = (Button)findViewById(R.id.btn2);
//btn2.setOnClickListener(btnListener);
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//---uraditi nešto---}
});