Zaawansowane programowanie UI na platformie Android

Podobne dokumenty
Dynamiczne i wydajne tworzenie interfejsu. Piotr Michałkiewicz

Systemy operacyjne na platformach mobilnych

Systemy operacyjne na platformach mobilnych

akademia androida Service, BroadcastReceiver, ContentProvider część IV

Powiadomienia w systemie Android

Tworzenie prezentacji w MS PowerPoint

Kompleksowe tworzenie aplikacji klasy Desktop z wykorzystaniem SWT i

Aktywności są związane z ekranem i definiują jego wygląd. Dzieje się to poprzez podpięcie do aktywności odpowiedniego widoku.

Szczegółowy opis zamówienia:

Android poradnik programisty

Podstawy technologii cyfrowej i komputerów

Programowanie obiektowe

VectraPortal. VectraPortal. wersja Instrukcja użytkownika Podstawowa funkcjonalność serwisu. [czerwiec 2016]

2017 Electronics For Imaging, Inc. Informacje zawarte w niniejszej publikacji podlegają postanowieniom opisanym w dokumencie Uwagi prawne dotyczącym

I. Spis treści I. Spis treści... 2 II. Kreator szablonów Tworzenie szablonu Menu... 4 a. Opis ikon Dodanie nowego elementu...

Tworzenie aplikacji na platformie Android

Programowanie dla Androida. Ubiquitous

Programowanie urządzeń mobilnych. dr inż. Juliusz Mikoda

dr Artur Bartoszewski dr Artur Bartoszewski - Aplikacje mobilne - Wykład

Projektowanie, tworzenie aplikacji mobilnych na platformie Android

[Android] Podstawy programowania

Formatowanie tekstu za pomocą zdefiniowanych stylów. Włączanie okna stylów. 1. zaznaczyć tekst, który chcemy formatować

PROBLEMY TECHNICZNE. Co zrobić, gdy natrafię na problemy związane z użytkowaniem programu DYSONANS

Dodanie nowej formy do projektu polega na:

Księgarnia PWN: Andrzej Jaskulski - AutoCAD 2010/LT Podstawy projektowania parametrycznego i nieparametrycznego

5.4. Efekty specjalne

Laboratorium 8 ( Android -pierwsza aplikacja)

Tworzenie wydajnych interfejsów. Autorzy: Piotr Michałkiewicz, 2 rok AiR Daniel Maksymow, 2 rok Informatyki

Instrukcja obsługi FiiO X7

Lokalizacja Oprogramowania

Instrukcja obsługi systemu zarządzania treścią w MDK

Jak przesłać mapę do urządzenia lub na kartę pamięci?

Programowanie aplikacji dla technologii mobilnych. mgr inż. Anton Smoliński

Efektywne tworzenie aplikacji webowych z wykorzystaniem AngularJS, HTML5 i JavaScript

Android tworzenie aplikacji mobilnych

Tworzenie bazy danych na przykładzie Access

Programowanie Urządzeń Mobilnych. Laboratorium nr 9,10

Programowanie Urządzeń Mobilnych. Część II: Android. Wykład 2

Mechanizm powiadomień

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Zdarzenia Klasa Application Powiadomienia Toast AlertDialog

Przypisy i przypisy końcowe

1. Dockbar, CMS + wyszukiwarka aplikacji Dodawanie portletów Widok zawartości stron... 3

Jak zainstalować i skonfigurować komunikator MIRANDA, aby wyglądał i funkcjonował jak Gadu Gadu Tutorial by t800.

Zasady tworzenia podstron

Spis treści CZĘŚĆ I. NIEPARAMETRYCZNE PROJEKTOWANIE 2D...31

Nowy interfejs w wersji 11.0 C8 BETA

Zaznaczanie komórek. Zaznaczenie pojedynczej komórki polega na kliknięciu na niej LPM

Rozdział 1. Przegląd bramofonu SAFE

ROZSZERZANIE MOŻLIWOŚCI...

Wstęp 7 Rozdział 1. OpenOffice.ux.pl Writer środowisko pracy 9

Instrukcja użytkownika Smart Orders

xmlns:prism= c. <ContentControl prism:regionmanager.regionname="mainregion" />

Rysowanie. Rysowanie - podstawy

1. Tworzenie prezentacji multimedialnych w programie Microsoft Office PowerPoint Artur Grabowski

Rozdział 5: Style tekstu

ROZDZIAŁ 1. PRZEGLĄD BRAMOFONU SAFE...

Lista wprowadzonych zmian w systemie Vario v. 3.3 od wydania do wydania

Spis treści. 1 Moduł Mapy 2

BAZY DANYCH Formularze i raporty

Layouty. Kilka layoutów

Politechnika Poznańska, Instytut Informatyki, TWO/GE. Programowanie dla ios

Podstawowe elementy GUI cz. 2 i 3 - zadania

WinSkład / WinUcz 15.00

Lokalizacja jest to położenie geograficzne zajmowane przez aparat. Miejsce, w którym zainstalowane jest to urządzenie.

Programowanie obiektowe i zdarzeniowe wykład 1 Wprowadzenie do programowania zdarzeniowego

Expo Composer Garncarska Szczecin tel.: info@doittechnology.pl. Dokumentacja użytkownika

Jak dodać swoją skrzynkę do klienta poczty Windows 10

Agenda. Activity cd Layouty Jednostki Dialogi LogCat Drugie Activity i Intents Serializacja Własne widoki Menu

Platforma e-learningowa

Spis treści. Rozdział 2. Graficzna oprawa witryny...z Stosowanie motywu...s...s.. 19

Ćwiczenie 6. Wiadomości ogólne.

SZCZEGÓŁOWY HARMONOGRAM SZKOLENIA

MagicInfo Express instrukcja obsługi

Ćwiczenie 1 Automatyczna animacja ruchu

Wyszukiwanie plików w systemie Windows

Adobe InDesign lab.1 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Podstawy pracy z aplikacją Układ strony... 2.

Dodawanie grafiki i obiektów

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.3

GLKit. Wykład 10. Programowanie aplikacji mobilnych na urządzenia Apple (IOS i ObjectiveC) #import "Fraction.h" #import <stdio.h>

AndroidManifest.xml. Plik manifestu opisuje podstawowe charakterystyki aplikacji i definiuje jej komponenty.

Grafika w aplikacjach lp. Jak zmienić kolor tła?

Programowanie w Javie

Dell Display Manager podręcznik użytkownika

Formatowanie komórek

Tablet bezprzewodowy QIT30. Oprogramowanie Macro Key Manager

Programowanie urządzeń mobilnych w systemie Android. Ćwiczenie 7 Wykorzystanie układu LinearLayout

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.3

Przygotuj za pomocą tabulatorów element formularza. Utwórz pole tekstowe i sformatuj tak, aby dół napisu w polu był dokładnie nad kropkami.

ROZDZIAŁ 1. PRZEGLĄD APLIKACJI SAFE...

6.4. Efekty specjalne

Autorzy. Zespół SABUR Sp. Z o.o. Wydanie Data. Sierpień SABUR Sp. Z o. o. Wszelkie prawa zastrzeżone

DARMOWA PRZEGLĄDARKA MODELI IFC

Część II Wyświetlanie obrazów

Rozdział 2. Konfiguracja środowiska pracy uŝytkownika

Qt sygnały i designer

1.3. Tworzenie obiektów 3D. Rysunek 1.2. Dostępne opcje podręcznego menu dla zaznaczonego obiektu

Ćwiczenie 23 Praca z plikiem.psd

Instrukcja obsługi Platformy nszkoła. Panel Ucznia

Jak dodać własny szablon ramki w programie dibudka i dilustro

Transkrypt:

Zaawansowane programowanie UI na platformie Android Karol Kuczmarski Zasoby, kontrolki, dialogi i cały ten jazz

Kim jestem? Programista w firmie Polidea głównie Android i Google App Engine projekt Apphance Programista Androida Taphoo Autor bloga xion.log (http://xion.org.pl) Moderator forum serwisu warsztat.gd Autor popularnego kursu C++ 2

Plan na dziś Wykorzystanie zasobów do modyfikacji wyglądu UI Nine patch drawables Listy stanów (state list drawables / color state lists) Animacje typu tween (przejścia) Praca z układami kontrolek (layouts) Wybór właściwego układu (podklasy ViewGroup) Ponowne używanie układów (include, merge, style/tematy) Korzystanie z powiadomień Dialogi Powiadomienia na pasku stanu Toasty 3

Wykorzystanie zasobów Drawables i animacje

Co dają nam zasoby? Określenie układu, wyglądu, a nawet zachowania interfejsu użytkownika Automatyczne uwzględnianie istotnych parametrów urządzenia i aktualnego systemu Rozmiar ekranu, orientacja, język, Łatwość tworzenia i używania zasobów Zaawansowane mechanizmy gotowe do wykorzystania Zasoby typu drawable, animacje, plurals, Niekiedy skorzystanie z zasobów jest koniecznością Najprostszy przykład: ikona aplikacji 5

Nine patch drawables Obrazy ze specjalnym rodzajem skalowania Służą do określania wyglądu obramowań i wnętrz Przyciski, pola tekstowe, okienka i inne Używane jak wartość dla android:background 6

9p drawables: jak działają? Obramowanie wyznaczane jest przez 9 łatek Cztery narożniki + cztery boki + środek Łatki odpowiednio się skalują Narożniki nie zmieniają rozmiarów Boki są powielane w jednym wymiarze Środek skaluje się w obu wymiarach 7

9p drawables: tworzenie Pojedynczy obrazek z jednopikselową ramką Białe i czarne rejony wyznaczają obszary skalowania Można też określić obszar zawartości elementu Wystarczy dowolny program graficzny Edytor (Draw 9 patch) dołączony do SDK 8

9p drawables: niekoniecznie 9 Wbrew nazwie, łatek nie musi być dokładnie 9 Bardziej skomplikowane obramowanie może mieć ich więcej Poszczególne obszary skalują się wtedy proporcjonalnie Przykład: obszar stały pośrodku boku obramowania Ramka nie musi też skalować się w obu wymiarach 9

Zasoby z listą stanów (state list) Domyślnie kontrolki zmieniają się, aby pokazać swoją interaktywność Przykład: wciskany przycisk rzeczywiście się wciska Jeśli modyfikujemy wygląd kontrolek, to powinniśmy wziąć ten fakt pod uwagę Osobne grafiki dla poszczególnych stanów kontrolki Jak zapewnić ich odpowiednie przełączanie?... Implementując OnClickListener!... Niezupełnie :-) Rozwiązanie: zasoby z listą stanów 10

State lists: definiowanie Zasobami z listami stanów definiujemy jako XML Każda pozycja to mapowanie: Zbiór stanów => odpowiedni zasób Kolejność jest istotna Ostatnia pozycja to zwykle zasób domyślny <?xml version="1.0" encoding="utf-8"?> <selector...> <item android:state_pressed="true" android:drawable="@drawable/button_pressed" /> <item android:state_focused="true" android:drawable="@drawable/button_focused" /> <item android:drawable="@drawable/button_normal" /> </selector> 11

State lists: możliwe stany android:state_enabled czy element jest aktywny Zwykle określa się zasób dla stanu nieaktywnego (false) android:state_focused czy element ma fokus Rzadko dotyczy trybu dotykowego (touch mode) android:state_pressed czy element jest wciśnięty android:state_checked czy element jest wybrany Pola wyboru (checkboxes) i przyciski radiowe Pozostałe: android:selected android:checkable android:window_focused 12

State list drawables Definiujemy jako pliki XML w res/drawable Elementy listy odwołują się do innych, już istniejących zasobów Mogą być nimi prawie dowolne drawable Gotowe zasoby pasują do wszystkich atrybutów typu drawable android:background, android:drawableleft, itd. Przykład podany wcześniej 13

Color state lists Definiujemy jako pliki XML w res/color Elementy listy bezpośrednio przechowują wartości kolorów Standardowe formaty #RGB, #RRGGBB, itd. Gotowe zasoby pasują do wszystkich atrybutów typu color android:backgroundcolor, android:textcolor, itd. <?xml version="1.0" encoding="utf-8"?> <selector...> <item android:state_pressed="true" android:color="#ffff0000"/> <item android:state_focused="true" android:color="#ff0000ff"/> <item android:color="#ff000000"/> </selector> 14

Animacje Android obsługuje dwa odmienne typy animacji dla widoków: Klatkowe (frame animations) Typu tween Animacje klatkowe działają jak zasoby typu drawable <?xml version="1.0" encoding="utf-8"?> <animation-list... android:oneshot="false"> <item android:drawable="@drawable/spinner1" android:duration="200" /> <item android:drawable="@drawable/spinner2" android:duration="200" /> <item android:drawable="@drawable/spinner3" android:duration="200" /> </animation-list> 15 spinner.setbackgroundresource(r.drawable.spinner_anim); ((AnimationDrawable)spinner.getBackground()).start();

Animacje typu tween Animacje tween pozwalają na geometryczne przekształcenia kontrolek: Zmianę położenia (translację - <translate>) Zmianę rozmiarów (skalowanie - <scale>) Obrót 2D wokół punktu - <rotate> Zmianę przezroczystości (alfy - <alpha>) Możliwe jest kontrolowanie sposobu interpolacji animowanych wartości Transformacje można składać w zbiory (<set>), aby zgrupowane animacje uruchamiały się jednocześnie 16

Przykład animacji typu tween <?xml version="1.0" encoding="utf-8"?> <set...> <alpha android:fromalpha="1.0" android:toalpha="0.0" android:duration="300" /> <scale android:interpolator="@android:anim/accelerate_interpolator" android:fromxscale="1.0" android:toxscale="0.0" android:fromyscale="1.0" android:toyscale="0.0" android:pivotx="0%" android:pivoty="100%" android:duration="300" /> </set> res/anim/example.xml 17

Stosowanie animacji typu tween Ręczne wczytywanie i kontrola animacji: Animation anim = AnimationUtils.loadAnimation(this, R.anim.example); view.startanimation(anim); Ustawianie jako przejść, np.: activity.overridependingtransition(r.anim.in, R.anim.out); // API 5+ viewanimator.setinanimation(r.anim.in); viewanimator.setoutanimation(r.anim.out); 18

Przykład animowanego przejścia <?xml version="1.0" encoding="utf-8"?> <!-- Odjazd w lewą stronę --> <translate... android:fromxdelta="0%p" android:toxdelta="-100%p" android:interpolator="@android:anim/accelerate_interpolator" android:duration="300"> </translate> res/anim/out.xml <?xml version="1.0" encoding="utf-8"?> <!-- Wjazd z prawej strony --> <translate... android:fromxdelta="100%p" android:toxdelta="0%p" android:interpolator="@android:anim/accelerate_interpolator" android:duration="300"> </translate> res/anim/in.xml 19

Praca z układami kontrolek Efektywne tworzenie layoutów

Tworzenie układów nie jest proste zwłaszcza dla programistów tradycyjnych GUI Kontrolki nie mają właściwości X i Y?! Układy wymuszają elastyczność, o którą w klasycznych PC-towych frameworkach trzeba dbać Nie można po prostu ustawić stałych pozycji/wymiarów Ceną jest większy stopień skomplikowania przy mniejszej swobodzie manewru private void MainForm_Resize(EventArgs e) { ctl.x = (Width ctl.width) / 2; ctl.y = (Height ctl.height) / 2; } Należy znać typy układów (podklasy ViewGroup na Androidzie) i ich przypadki użycia 21

Który *Layout wybrać? Prawie zawsze odpowiedzią jest RelativeLayout Pewne wyjątki: Tylko jedna kontrolka - FrameLayout Układ przypomina tabelę - TableLayout Układ jest liniowy i: Wszystkie elementy mają stały rozmiar w jednostkach bezwzględnych (dip) lub Wszystkie elementy mają rozmiar proporcjonalny do rozmiaru całego układu (android:layout_weight) - LinearLayout 30dip 40dip 30dip 45% 55% 22

Przykład: holy grail http://www.alistapart.com/articles/holygrail 23

Rozwiązanie: tylko jeden RelativeLayout <RelativeLayout...> <View android:id="@+id/header" android:layout_alignparenttop="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/footer" android:layout_alignparentbottom="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/left" android:layout_alignparentleft="true" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_width="70dip" android:layout_height="match_parent" /> <View android:id="@+id/right" android:layout_alignparentright="true" android:layout_width="70dip" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" /> <View android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_torightof="@+id/left" android:layout_toleftof="@+id/right" /> </RelativeLayout> 24

z odpowiednio wyrównanymi <RelativeLayout...> <View android:id="@+id/header" android:layout_alignparenttop="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/footer" android:layout_alignparentbottom="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/left" android:layout_alignparentleft="true" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_width="70dip" android:layout_height="match_parent" /> <View android:id="@+id/right" android:layout_alignparentright="true" android:layout_width="70dip" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" /> <View android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_torightof="@+id/left" android:layout_toleftof="@+id/right" /> </RelativeLayout> 25

i wymierzonymi kontrolkami <RelativeLayout...> <View android:id="@+id/header" android:layout_alignparenttop="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/footer" android:layout_alignparentbottom="true" android:layout_width="match_parent" android:layout_height="50dip"/> <View android:id="@+id/left" android:layout_alignparentleft="true" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_width="70dip" android:layout_height="match_parent" /> <View android:id="@+id/right" android:layout_alignparentright="true" android:layout_width="70dip" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" /> <View android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/header" android:layout_above="@id/footer" android:layout_torightof="@+id/left" android:layout_toleftof="@+id/right" /> </RelativeLayout> 26

Ponowne wykorzystanie elementów UI Zasada DRY (Don t Repeat Yourself) działa też przy konstruowaniu interfejsu W Androidzie jest to możliwe poprzez wyodrębnianie: Powtarzalnych wartości do postaci zasobów (res/values) Właściwości kontrolek do postaci styli/tematów Grup kontrolek do postaci dołączanych układów <?xml version="1.0" encoding="utf-8"> <resources> <color name="background_color">#c0ffee</color> <color name="text_color">#face</color> </resources> 27

Ponowne wykorzystanie: style widoków Style pozwalają na zdefiniowanie zestawu wartości dla atrybutów widoków <?xml version="1.0" encoding="utf-8"> <resources> <style name="button"> <item name="android:textcolor">@color/textcolor</item> <item name="android:gravity">right</item> <item name="android:paddingleft">15dip</item> <item name="android:layout_height">wrap_content</item> </style> </resources> <Button android:id="@+id/my_button" style="@style/button"/> 28

Style widoków: dziedziczenie Dla stylu możemy ustawić styl nadrzędny Właściwości są dziedziczone, ale możemy je nadpisywać <style name="redbutton" parent="@style/button"> <item name="android:background">#f00</item> </style> Jeżeli nadrzędnym jest nasz własny styl, możemy używać notacji kropkowej: <style name="button.red"> <item name="android:background">#f00</item> </style> <style name="button.red.big"> <item name="android:textsize">30dip</item> </style> 29

Ponowne wykorzystanie układów Układy kontrolek nie muszą być wykorzystywane bezpośrednio (np. w Activity.setContentView) W razie potrzeby układ można załadować z zasobu przy pomocy klasy LayoutInflater W ten sposób można tworzyć dynamiczne układy kontrolek LayoutInflater inflater = getlayoutinflater(); for (...) { View element = inflater.inflate(r.layout.item, null, false); //... container.addview(element); } 30

Ponowne wykorzystanie: <include> i <merge> Możliwe jest też włączanie układu do XML-a innego układu za pomocą elementu <include> <RelativeLayout...> <include layout="@layout/top_bar" android:layout_alignparentop="true" /> <LinearLayout android:id="@+id/main_content"... /> </RelativeLayout> Jeśli włączany układ ma <merge> jako główny element, wtedy wstawiana jest tylko jego zawartość <merge...> <Button android:id="@+id/button1"... /> <Button android:id="@+id/button2"... /> </merge> 31

Korzystanie z powiadomień i ich upiększanie

Android notyfikacjami stoi System oferuje kilka opcji powiadomień Zajmiemy się trzema najczęściej używanymi: Toasty Powiadomienia na pasku stanu Dialogi Różnią się one m.in. inwazyjnością i stopniem możliwej interakcji użytkownika Interaktywność Inwazyjność Toasty żadna mała Pasek stanu mała żadna Dialogi pełna duża 33

Toasty Krótko widoczne informacje wyświetlane domyślnie pośrodku dolnej części ekranu Najprostsza wersja: sam tekst Toast.makeText(getContext(), R.string.toast_text, Toast.LENGTH_SHORT).show(); Bardziej skomplikowana: własny układ kontrolek Toast toast = new Toast(getContext()); toast.setduration(toast.length_long); toast.setview(toastview); toast.show(); 34

Notyfikacje na pasku stanu Reprezentują zdarzenia oczekujące akcji użytkownika, np. przychodzące wiadomości Składają się z: Ikony na pasku stanu Tekstu powiadomienia (ticker text) na pasku stanu Widoku pokazywanego po rozwinięciu paska Powiadomieniom mogą towarzyszyć inne sygnały Dźwięki, wibracje, miganie diody LED Interakcja użytkownika z powiadomieniem powoduje wysłanie ustalonego wcześniej intenta 35

Przykład notyfikacji tekstowej Notification notification = new Notification(R.drawable.icon, "Hello world!", System.currentTimeMillis()); Intent tapintent = new Intent(this, MyActivity.class); PendingIntent contentintent = PendingIntent.getActivity(this, tapintent, 0); notification.setlatesteventinfo(this, "Hello", "Nice to meet you.", contentintent); NotificationManager nm = (NotificationManager) getsystemservice(notification_service); nm.notify(1, notification); //... nm.cancel(1); 36

Własne widoki w notyfikacjach Notyfikacje mogą zawierać bardziej skomplikowany UI niż tylko sam tekst Paski postępu ściągania plików, kontrolki odtwarzania muzyki, itp. W tym celu należy użyć zdalnych widoków (RemoteViews), podając: Identyfikator układu kontrolek (R.layout) Opcjonalne modyfikacje właściwości kontrolek, aplikowane po załadowaniu układu Nie można użyć View bezpośrednio, bo notyfikacje istnieją w procesie systemowym, a nie aplikacji 37

Przykład: pasek postępu <?xml version="1.0" encoding="utf-8"?> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dip"> <ProgressBar android:id="@+id/progress_bar" style="?android:attr/progressbarstylehorizontal" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> 38 res/layout/notification_progress.xml

Pasek postępu: użycie RemoteViews RemoteViews contentview = new RemoteView(getPackageName(), R.layout.notification_progress); contentview.setprogressbar(r.id.progress_bar, 100, 0, false); Notification notification = new Notification(...); notification.flags = Notification.FLAG_ONGOING_EVENT; notification.contentintent = PendingIntent.getActivity(...); notification.contentview = contentview; notificationmanager.notify(notification_id, notification); // update notification.contentview.setprogressbar(r.id.progress_bar, 100, percentage, false); notificationmanager.notify(notification_id, notification); 39

stworzenie notyfikacji RemoteViews contentview = new RemoteView(getPackageName(), R.layout.notification_progress); contentview.setprogressbar(r.id.progress_bar, 100, 0, false); Notification notification = new Notification(...); notification.flags = Notification.FLAG_ONGOING_EVENT; notification.contentintent = PendingIntent.getActivity(...); notification.contentview = contentview; notificationmanager.notify(notification_id, notification); // update notification.contentview.setprogressbar(r.id.progress_bar, 100, percentage, false); notificationmanager.notify(notification_id, notification); 40

i jej aktualizacja RemoteViews contentview = new RemoteView(getPackageName(), R.layout.notification_progress); contentview.setprogressbar(r.id.progress_bar, 100, 0, false); Notification notification = new Notification(...); notification.flags = Notification.FLAG_ONGOING_EVENT; notification.contentintent = PendingIntent.getActivity(...); notification.contentview = contentview; notificationmanager.notify(notification_id, notification); // update notification.contentview.setprogressbar(r.id.progress_bar, 100, percentage, false); notificationmanager.notify(notification_id, notification); 41

Dialogi Android oferuje kilka wbudowanych klas dialogów na typowe (i mniej typowe) okazje AlertDialog i jego podklasy, np. ProgressDialog Możemy też używać klasy Dialog bezpośrednio Za pomocą własnych układów kontrolek i styli, możemy dostosować dialogi do wyglądu naszej aplikacji 42

Przypadki użycia dialogów AlertDialog ze standardowym układem Proste komunikaty o błędach, potwierdzenia operacji, dialogi typu Loading, itp. AlertDialog z własnym układem kontrolek Tworzony poprzez AlertDialog.Builder metodą setview() Odpowiedni do bardziej skomplikowanych komunikatów Dialog lub własna podklasa Dialog Gdy chcemy mieć pełną kontrolę nad wyglądem dialogu Gdy chcemy mieć interaktywne kontrolki w dialogu Przykład: własne menu opcji 43

Przykład własnego dialogu public class CustomDialog extends Dialog { public CustomDialog(Context context) { super(context, android.r.style.theme_translucent_notitlebar_fullscreen); getwindow().getattributes().windowanimations = R.style.DialogTransition; } setcontentview(r.layout.dialog); ((Button)findViewById(R.id.dialog_button)).setOnClickListener(buttonListener); private OnClickListener buttonlistener = new OnClickListener(){ } }; public void onclick(view view) { dismiss(); Toast.makeText(getContext(), "Dialog closed", Toast.LENGTH_SHORT).show(); } 44

Style dla dialogów Domyślnie dialogi używają stylu android.r.style.theme_dialog Zajmują tylko część ekranu Mają tytuł i systemową ramkę z paddingiem dookoła Używając innych styli, możemy eliminować niechciane elementy (np. android.r.style.theme_notitlebar) Największe możliwości daje android.r.style.theme_translucent_notitlebar_fullscreen, ale wymaga ręcznego pozycjonowania dialogu <?xml version="1.0" encoding="utf-8"?> <RelativeLayout... android:layout_width="250dip" android:layout_height="300dip" android:layout_gravity="center">... </RelativeLayout> 45

Przykład stylizowanego dialogu 46 <RelativeLayout width=dialogwidth height=dialogheight layout_gravity=center> c <RelativeLayout width=match_parent height=match_parent layout_marginbottom=buttonsheight/2> <LinearLayout width=match_parent height=buttonsheight layout_alignparentbotom=true>

Animacje przejścia dla dialogów Modyfikując atrybuty okna (Window) dialogu, możemy ustawić dla niego animacje przejścia..chociaż teoretycznie to nie powinno działać :-) <style name="dialogtransition"> <item name="android:windowenteranimation"> @anim/in</item> <item name="android:windowexitanimation"> @anim/out</item> </style> getwindow().getattributes().windowanimations = R.style.DialogTransition; 47

Na zakończenie

Co jeszcze?... Pozostałe rodzaje zasobów Samych zasobów typu drawable jest kilkanaście! Lokalizacja Media: audio i wideo Nowości z wersji 3.0 Fragmenty Action Bar Drag & drop Schowek 49

Przydatne źródła Specyfikacje systemowych styli i tematów http://developer.android.com/reference/android/r.style.html http://developer.android.com/guide/topics/ui/themes.html#platformstyles Wskazówki odnośnie konwencji UI w Androidzie http://www.androidpatterns.com/ http://www.androiduipatterns.com/ http://developer.android.com/guide/practices/ui_guidelines/index.html Optymalizowanie aplikacji pod 3.0 http://developer.android.com/guide/practices/optimizing-for-3.0.html 50

Dziękuję za uwagę :-)