Obsah UI model KeyEvent View Tvorba vlastních komponent Canvas Matrix Vlastní EditText LayoutInflater Dotykové události MotionEvent Dynamické přidání View 2
UI model Androida View Základní stavební kámen pro UI komponenty Základem pro Widgety - interaktivní komponenty Obdélníková oblast Zodpovědná za vykreslování a zpracování událostí Viewgroup Speciální View Může obsahovat potomky (children) Základem pro layouty a view kontejnery 3
Přehled Základní widgety Button TextView EditText ListView CheckBox RadioButton Spinner Základní layouty LinearLayout FrameLayout RelativeLayout 4
Pokročilejší widgety AutoCompleteTextView Podobá se spíš EditTextu než TextView Navrhuje text v průběhu psaní Gallery Zobrazuje obrázky (centrovaně) v horizontálním seznamu ImageSwitcher Plynulá výměna obrázků TextSwitcher Při zavolání settext(charsequence) dojde k animaci 5
KeyEvent Událost kláves a tlačítek Mají definovovaný tzv.,,key code Integer konstanta Např. KeyEvent.KEYCODE_VOLUME_UP KeyEvent.KEYCODE_W KeyEvent.KEYCODE_DPAD_CENTER KeyEvent.KEYCODE_ENTER Každý stisk se skládá ze sekvence KeyEventů Začíná KeyEvent.ACTION_DOWN Končí KeyEvent.ACTION_UP 6
7 Základní metody View Konstruktory 1. Volán při vytvoření z kódu 2. Volán při vytvořená z XML layoutu Měl by zpracovávat všechny možné atributy z XML onfinishinflate() Závoláno poté, co View bylo načteno z XML layoutu onmeasure(int, int) Změří View včetně obsahu Je nezbytné nastavit šířku a výšku setmeasureddimension(int, int) Jinak IllegalStateException onlayout(boolean, int, int, int, int) Zavoláno v případě, kdy je třeba sdělit šířku a výšku potomkovi layoutu onsizechanged(int, int, int, int) Zavoláno v případě změny velikosti View
8 Základní metody View pokračování ondraw(canvas) Zavoláno v případě, kdy se má View vykreslit Zde se provádí samotné vykreslení obsahu View na Canvas invalidate() Manuálně provede překreslení (zavolá se ondraw()) onkeydown(int, KeyEvent) Zavoláno po KeyEvent.ACTION_DOWN onkeyup(int, KeyEvent) Zavoláno po KeyEvent.ACTION_UP ontrackballevent(motionevent) Zavoláno při pohybu trackballem ontouchevent(motionevent) Zavoláno při pohybu ukazatelem na obrazovce
9 Základní metody View pokračování onfocuschanged(boolean, int, Rect) Zavoláno při změně fokusu onwindowfocuschanged(boolean) Zavoláno v případě, kdy okno obsahující View získá nebo ztratí fokus onattachedtowindow() Zavoláno v případě připojení View do okna ondetachedfromwindow() Zavoláno v případě odpojení View z okna onwindowvisibilitychanged(int) Zavoláno v případě změny viditelnosti okna, které obsahuje View
10 Tvorba vlastních komponent Důvody Tvorba kompletně nové komponenty Např. ukazatel aktuální stránky v průvodci (ViewFlipperu) Úprava již existujících View Vzhled Změna písma (pozn.: font nelze nastavovat widgetu v XML, pouze programově) Funkčnost Úprava či vytvoření nových událostí Vytvoření jedné komponenty z více View např. vlastní ComboBox Vždy se dědí od nějakého View
11 Canvas Třída pro kreslení na plátno Lze malovat např. Obdélník drawrect(rect, Paint) Bod drawpoint(x, y, Paint) Cestu drawpath(path, Paint) Bitmapu drawbitmap(bitmap, Matrix, Paint) Úsečku drawline(startx, starty, stopx, stopy, Paint) Text drawtext(text, x, y, Paint) Vyplnění Canvasu barvou drawcolor(color) třída Paint definuje styl (barva, tloušťka, výplň ) pro daný objekt, který se do Canvasu kreslí setmatrix(matrix) nastavení matice transformace pro budoucí kreslení
12 Matrix Slouží k transformaci objektu Obsahuje matici 3x3 setscale setskew settranslate setrotate postscale posttranslate postrotate Hodnoty pole, které nastaví getvalues(float[] values) 0 : Měřítko X 1 : Zkosení X 2 : Transformace X 3 : Měřítko Y 4 : Zkosení Y 5 : Transformace Y 6 : Perspektiva 7 : Perspektiva 8 : Perspektiva 0 1 2
13 Vlastní EditText s podtrháváním řádků příklad class LinedEditText extends EditText { private Rect mrect; private Paint mpaint; public LinedEditText(Context context, AttributeSet attrs) { super(context, attrs); mrect = new Rect(); mpaint = new Paint(); mpaint.setstyle(paint.style.stroke); mpaint.setcolor(0x800000ff); } @Override protected void ondraw(canvas canvas) { int count = getlinecount(); Rect r = mrect; Paint paint = mpaint; for (int i = 0; i < count; i++) { int baseline = getlinebounds(i, r); canvas.drawline(r.left, baseline + 1, r.right, baseline + 1, paint); } super.ondraw(canvas); }}
14 Použití vlastní komponenty v XML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linearlayout1" android:layout_width="fill_parent" android:layout_height="fill_parent"> <cz.cvut.fit.example.linededittext android:text="linededittext" android:id="@+id/linededittext1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/white" android:padding="5dp" android:scrollbars="vertical" android:fadingedge="vertical" android:gravity="top" android:textsize="22sp" android:capitalize="sentences" /> </LinearLayout>
15 Výsledek EditTextu s podtrháváním
16 LayoutInflater Umožňuje naplnit objekt View obsahem z XML Instanci získáme pomocí LayoutInflater.from(context); Naplňené View získáme pomocí těchto metod: inflate(int resource, ViewGroup root); Vrátí View Pokud root není null, automaticky do něj přidá dané View inflate (XmlPullParser parser, ViewGroup root) 1. LayoutInflater li = LayoutInflater.from(this); 2. LinearLayout ll=(linearlayout) li.inflate(r.layout.main, null);
17 Dotykové události Přepsáním ontouchevent(motionevent event)ve View můžeme reagovat na dotykové události Alternativa implementace ontouchlisteneru a nastavení ho View view.setontouchlistener(ontouchlistener); MotionEvent poskytuje všechny potřebné informace dané události
18 MotionEvent getaction() Vrátí ID akce, kterou uživatel provedl MotionEvent.ACTION_DOWN Uživatel se dotkl obrazovky MotionEvent.ACTION_UP Uživatel se přestal dotýkat obrazovky MotionEvent.ACTION_MOVE Uživatel provedl pohyb na dotekové obrazovce (mezi ACTION_DOWN a ACTION_UP) MotionEvent.ACTION_CANCEL Gesto bylo zrušeno MotionEvent.ACTION_OUTSIDE Uživatel provedl dotyk mimo aktuální View Pomocí event.getx() a event.gety() můžeme získat aktuální souřadnice doteku
19 MotionEvent getactionmasked() Vrátí profiltrované ID bez bitu označujícího index doteku Alternativa k event.getaction() & MotionEvent.ACTION_MASK; Kromě hodnot z předešlého slajdu může vrátit: MotionEvent.ACTION_POINTER_DOWN Uživatel provedl paralelní dotyk (multitouch) MotionEvent.ACTION_POINTER_UP Uživatel se přestal jedním ukazatelem dotýkat Pomocí event.getactionindex() můžeme získat index doteku k aktuální akci Pomocí event.getx(index) a event.gety(index) můžeme získat aktuální souřadnice daného doteku
20 Posouvání obrázku ukázka 1. public class MyCustomImageView extends ImageView { 2. private float lastmotionx; 3. private float lastmotiony; 4. private Matrix matrix = new Matrix(); 5. @Override 6. public boolean ontouchevent(motionevent event) { 7. switch (event.getaction()) { 8. case MotionEvent.ACTION_DOWN: //uzivatel se zacal dotykat View 9. lastmotionx = event.getx(); 10. lastmotiony = event.gety(); 11. break; 12. case MotionEvent.ACTION_MOVE: //uzivatel provedl pohyb 13. int deltax = (int) (event.getx() - lastmotionx); 14. int deltay = (int) (event.gety() - lastmotiony); 15. 16. //nastavime transformaci a posuneme obrazek 17. matrix.posttranslate(deltax, deltay); 18. setimagematrix(matrix); 19. 20. lastmotionx = event.getx(); 21. lastmotiony = event.gety(); 22. } 23. return true; 24. } 25....
21 Dynamické přidání View Pokud potřebujeme dynamicky přidat nějaké View do ViewGroup, použijeme metodu viewgroup.addview(view) popř. viewgroup.addview(view, position) 1. 2. 3. 4. TextView tw=new TextView(this); tw.settext("text"); LinearLayout layout = (LinearLayout) findviewbyid(r.id.layout); layout.addview(tw, 0); View může mít maximálně jednoho rodiče Pokud je View již v nějakém layoutu a pokusíme se ho přidat do jiného layoutu, systém vyhodí IllegalStateException
Dynamické odebrání View Pro odebrání View z ViewGroup slouží tyto metody: viewgroup.removeviewat(index); viewgroup.removeview(view); viewgroup.removeviews(start, count); viewgroup.removeallviews(); 22