Uživatelské rozhraní Layouty FrameLayout LinearLayout RelativeLayout TableLayout ScrollView Taby Dialogy ViewFlipper 2
FrameLayout Nejjednodušší a nejzákladnější layout Prvky Nelze nijak pozicovat Všechny jsou umístěny do levého horního rohu Málo používané a použitelné Vhodné pro testovací účely 3
4 LinearLayout Všechny prvky jsou zarovnávány vertikálně či horizontálně android:orientation=["vertical" "horizontal"] Možnost vnořování do sebe navzájem nepřehlednost kódu náročnější na výkon Prvky mohou mít definované layout_weight - určuje důležitost zobrazení prvku vůči ostatním
RelativeLayout Prvky jsou pozicovány relativně proti sobě, např. Prvek B je napravo od prvku A Prvek B je zarovnán napravo vůči prvku A Výhody: Přehlednost kódu Méně výpočetně náročné Bezpečnější pozicování (zodpovědnější chování UI) Nevýhody: Každý relativně pozicovaný prvkek musí mít android:id Návrh se obtížněji upravuje 5
RelativeLayout - příklad <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/entry" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/entry" android:layout_alignparentright="true" android:text="ok" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toleftof="@id/ok" android:layout_aligntop="@id/ok" android:text="cancel" /> </RelativeLayout> 6
7 TableLayout - příklad <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchcolumns="1"> <TableRow> <TextView android:padding="3dip" android:text="open"/> <TextView android:text="ctrl-o" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:text="save as... " android:padding="3dip" /> <TextView android:text="ctrl-shift-s" android:gravity="right" android:padding="3dip" /> </TableRow> </TableLayout> NEPOUŽÍVAT K POZICOVÁNÍ!
8 Tipy pro tvorbu uživatelského rozhraní DIP (Density Independent Pixel) Jednotka, jejíž hodnota je vypočítána na základě velikosti a rozlišení displeje Zaručuje zhruba stejnou velikost UI komponent na všech displejích SP Obdoba DIP pro velikost písma UI je možné vytvářet i programově Vhodné při vytváření Vlastních UI komponent Adaptéru Zodpovědnost Optimalizace pro podporované typy displejů (v AndroidManifest.xml) UI je funčkční i v případě otočení zařízení od 90 (nebo zakázat landscape zobrazení activity)
9 ScrollView Umožňuje scrolování, pokud velikost vnořených prvků přesahuje fyzickou velikost displeje Pouze jeden vnořený element <ScrollView xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="fill_parent"> <LinearLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical"> <Button android:text="button" android:layout_width="wrap_content" android:layout_height="wrap_content" />... <Button android:text="button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </ScrollView>
12 Taby Nadefinujeme si TabHost layout s umístěním TabWidgetu (přepínání tabů) a FrameLayoutu (obsah tabu) 1. <?xml version="1.0" encoding="utf-8"?> 2. <TabHost xmlns:android="http://schemas.android.com/apk/res/android" 3. android:id="@android:id/tabhost" 4. android:layout_width="fill_parent" 5. android:layout_height="fill_parent"> 6. <LinearLayout 7. android:orientation="vertical" 8. android:layout_width="fill_parent" 9. android:layout_height="fill_parent" 10. android:padding="5dp"> 11. <TabWidget 12. android:id="@android:id/tabs" 13. android:layout_width="fill_parent" 14. android:layout_height="wrap_content" /> 15. <FrameLayout 16. android:id="@android:id/tabcontent" 17. android:layout_width="fill_parent" 18. android:layout_height="fill_parent" 19. android:padding="5dp" /> 20. </LinearLayout> 21.</TabHost>
13 TabActivity Musíme vytvořit Aktivitu, která se bude starat o samotné přepínání tabů. Tato třída dědí od TabActivity 1. public class MyTabActivity extends TabActivity { 2. @Override 3. protected void oncreate(bundle savedinstancestate) { 4. super.oncreate(savedinstancestate); 5. setcontentview(r.layout.main_tab); // Nastavi aktivite layout z predchoziho slidu 6. 7. Resources res = getresources(); // Odkaz na Resources pro vlozeni obrazku 8. TabHost tabhost = gettabhost(); // TabHost aktualni aktivity 9. TabHost.TabSpec spec; // Znovupouzitelny TabSpec specifikace pro kazdy tab 10. Intent intent; // Znovupouzitelny Intent pro taby, ktere spousti aktivity 11. 12....// pridani tabu nasledujici slidy 13. 14. setdefaulttab(0); // nastavi index tabu, ktery se zobrazi jako defaultni 15. } 16. }
14 TabActivity Spouštění aktivit Pro každý TabSpec nastavíme Intent, který se po vybrání daného tabu v něm spustí 1. intent=new Intent(this, MyTab1.class);//nastaveni aktivity, kterou chceme spustit 2. spec = tabhost.newtabspec(tag_tab1);//nastavebi unikatniho TAGu pro dany tab 3. //nastaveni textu a obrazku zalozky 4. spec.setindicator("tab 1", res.getdrawable(r.drawable.ic_tab_example)); 5. spec.setcontent(intent); //prirazeni intentu, ktery se po vyberu v tabu spusti 6. tabhost.addtab(spec);//pridani tabu
15 TabActivity Změna View Pro každý TabSpec nastavíme TabContentFactory, kde přepíšeme metodu createtabcontent a vrátíme View, které chceme v daném tabu zobrazit 1. spec = tabhost.newtabspec(tag_tab3); 2. spec.setindicator("tab 3", res.getdrawable(r.drawable.ic_tab_example)); 3. spec.setcontent(new TabContentFactory() { 4. //Zde vratime view, ktere se po prepnuti tabu zobrazi 5. @Override 6. public View createtabcontent(string tag) { 7. TextView tw = new TextView(MyTabActivity.this); 8. tw.settext("hello, tab!"); 9. return tw; 10. } 11. }); 12. tabhost.addtab(spec);//pridani tabu
16 Dialogy Předání (důležité) informace uživateli Získání informace od uživatele Vytvářeny v překryté metodě oncreatedialog() Přístup a nastavení z hlavního vlákna protected Dialog oncreatedialog(int id) { Dialog dialog; switch(id) { case DIALOG_PAUSED_ID: break; case DIALOG_GAMEOVER_ID: break; default: dialog = null; } return dialog; showdialog(dialog_paused_id); }
17 Operace s dialogy dismissdialog() Zavře dialog cancel() Stejné jako dismissdialog() a navíc zavolá DialogInterface.OnCancelListener removedialog(int) Pouze při použití oncreatedialog(int) Zruší referenci na dialog a zavolá dismissdialog(), pokud se zobrazuje Nastavení listenerů přes DialogInterface OnDismissListener OnCancelListener zavolán při zrušení dialogu uživatelem nebo při stisku BACK
18 AlertDialog Velice jednoduchá implementace Lze nastavit titulek, obsah zprávy, maximálně tři tlačítka, položky výběru (checkbox, radiobutton) AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage("are you sure you want to exit?").setcancelable(false).setpositivebutton("yes", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { MyActivity.this.finish(); } }).setnegativebutton("no", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create();
Další možnosti AlertDialogu Se seznamem S RadioButtony 19
20 Vlastní vzhled dialogu 1. Vytvoříme si xml s vlastním vzhledem: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout_root" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp" > <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginright="10dp /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="fill_parent" android:textcolor="#fff"/> </LinearLayout>
21 Vlastní vzhled dialogu pokračování Context mcontext = getapplicationcontext(); Dialog dialog = new Dialog(mContext); dialog.setcontentview(r.layout.custom_dialog); dialog.settitle("custom Dialog"); TextView text = (TextView) dialog.findviewbyid(r.id.text); text.settext("hello, this is a custom dialog!"); ImageView image = (ImageView) dialog.findviewbyid(r.id.image); image.setimageresource(r.drawable.android);
22 ProgressDialog úvod protected Dialog oncreatedialog(int id) { case DIALOG_PROGRESS: mprogressdialog = new ProgressDialog(AlertDialogSamples.this); mprogressdialog.seticon(r.drawable.alert_dialog_icon); mprogressdialog.settitle(r.string.select_dialog); mprogressdialog.setprogressstyle(progressdialog.style_horizontal); mprogressdialog.setmax(max_progress); mprogressdialog.setbutton(dialoginterface.button_positive, gettext(r.string.alert_dialog_hide), new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int whichbutton) { } }); mprogressdialog.setbutton(dialoginterface.button_negative, gettext(r.string.alert_dialog_cancel), new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int whichbutton) { } }); return mprogressdialog; } Pokračování v 9. přednášce
23 ViewFlipper Widget pro rychlé přepínání mezi jednotlivými obrazovkami Vhodné pro tvorbu průvodců <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ViewFlipper android:id="@+id/viewflipper01" Jednotlivé obrazovky android:layout_width="wrap_content" průvodce umístíme do android:layout_height="wrap_content"> zvláštních souborů ve <include složce layout layout="@layout/screen1" /> <include layout="@layout/screen2" /> <include layout="@layout/screen3" /> </ViewFlipper>
24 ViewFlipper - pokračování <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:background="@drawable/bottom_bar" android:gravity="center_vertical"> <Button android:layout_width="100dp" android:layout_height="wrap_content" android:id="@+id/button02" android:layout_alignparentright="true" android:text="next" /> <Button android:layout_height="wrap_content" android:layout_width="100dp" android:id="@+id/button01" android:text="previous" android:layout_alignparentleft="true" /> </RelativeLayout> </RelativeLayout> Vytvoříme wizard-like dolní lištu pomocí RelativeLayout Pozadí nebudeme referencovat na to, co je v systému, a raději si ho zkopírujeme do své aplikace např. ze složky sdk/platforms/android-10
25 ViewFlipper - pokračování Následujícím způsobem vytvoříme jednotlivé obrazovky průvodce a pojmenujeme screen[1-3].xml Pozn.: <merge> není nutné použít a obsah obrazovek průvodce můžeme rovnou psát do <ViewFlipper> <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="flipper Content 1" /> </merge>
ViewFlipper pokračování public class ViewFlipperExample extends Activity implements OnClickListener { private Button next; private Button previous; private ViewFlipper vf; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); vf = (ViewFlipper) findviewbyid(r.id.viewflipper01); previous = (Button) findviewbyid(r.id.button01); next = (Button) findviewbyid(r.id.button02); next.setonclicklistener(this); previous.setonclicklistener(this); } @Override public void onclick(view v) { if (v == next) { vf.shownext(); } if (v == previous) { vf.showprevious(); } }} 26