Widgety

Widgety to miniaturowe aplikacje które mogą być zagnieżdżone w innych aplikacjach. Najczęściej dotyczy to zagnieżdżania w aplikacji Home Screen tj. pulpitu. My zrobimy prosty widget który wyświetla wartość zmiennej x, a przy każdym kliknięciu guzika powiększa x o 1 i ponownie go wyświetla. 



Plik layoutu


Tworzymy nowy zwykły androidowy projekt. Powstałą aktywność MainActivity i związany z nią plik layoutu możemy przerobić wg własnych upodobań. Będzie on wyświetlany przy pierwszym uruchomieniu aplikacji i może spełniać np. rolę informacyjną.  W pierwszej kolejności dodajemy plik xml określający layout naszego widgeta. Do katalogu layout (będącego podkatalogiem katalogu res) dodajemy plik xml. Swój nazwałem layout_widgeta.xml


Zawartość pliku wygląda tak:




Pamiętaj, że w przypadku widgetów nie wszystkie layouty i komponenty są dozwolone. Możesz używać tylko poniższych.


Layouty:

FrameLayout

LinearLayout

GridLayout

RelativeLayout


Komponenty:

AnalogClock

Button

Chronometer

ImageButton

ImageView

ProgressBar

TextView

ViewFlipper

ListView

GridView

StackView

AdapterViewFlipper


Plik konfiguracji widgetu


W tym pliku definiujemy ustawienia inicjalizacyjne widgetu, takie jak minimalna szerokość i wysokość, częstotliwość odświeżania.

Do katalogu res dodajemy podkatalog xml a w nim tworzymy nowy plik XML. Ja swój nazwałem widget_provider.xml
Jego zawartość wygląda tak:




Zadeklarowałem wcześniej stworzony plik layoutu jako layout wczytywany przy starcie aplikacji, minimalną szerokość i wysokość widgetu. Parametr updatePeriodMillis definiuje jak często ma być wywoływana (dzieje się to automatycznie) metoda onUpdate obiektu klasy dziedziczącej po AppWidgetProvider, a będącej odpowiedzialną za aktualizowanie widgetu.  



Klasa odpowiedzialna za aktualizację widgetu


Tworzymy teraz nową klasę, dziedziczącą po klasie AppWidgetProvider.  Najważniejsza jest w niej (wynikająca z implementacji) metoda onUpdate. Ta metoda jest wywoływana w regularnych cyklach (zdefiniowanych u nas w pliku widget_provider) i służy do aktualizowania widgetu. Komponentów na widgecie nie możemy podpiąć tak jak zwykłych komponentów w zwykłych aplikacjach. Tj. nie podpinamy ich do obiektów klas rozszerzających klasę View, a do obiektów klasy RemoteViews. Wynika to z faktu, że nasza metoda zarządza obiektami z innego widoku (zdalnego) i tak właśnie trzeba to robić przy widgetach. W linii 21 podpinamy layout naszego widgetu. W linii 22 określamy obsługę zdarzeń dla kliknięcia naszego przycisku (zdefiniowanego w pliku layout_widgeta.xml). Obsługa zdarzeń nie polega jednak na definicji tradycyjnego listenera z bezpośrednim kodem czynności, a na wysłaniu intencji która jest odbierana przez Broadcast Receiver w innym miejscu.





Klasa odbierająca intencję




Do projektu dodajemy jeszcze klasę dziedziczącą po BroadcastRecever'ze (nic nowego, pojawiał się już we wcześniejszych lekcjach). Klasa ta służy nam do odbioru wywołanej z klasy AktualizacjaWidgeta intencji. Odbiór i sprawdzenie czy to właściwa intencja następuje w metodzie onReceive. Sprawdzamy jednak czy intencja która „przyszła” to intencja pl.jsystems.akcje.IKS_PLUS_PLUS, na wypadek gdyby nasza aplikacja mogła być odbiorcą jeszcze jakichś intencji (musiałaby jednak zostać zarejestrowana jako odbiorca takich intencji w pliku manifestu).



Aktualizacja pliku manifestu


Teraz musimy w pliku manifestu umieścić niezbędne informacje na temat klasy obsługującej aktualizowanie widgeta, oraz klasy odpowiedzialnej za obsługę intencji pl.jsystems.widget.akcje.IKS_PLUS_PLUS. Zawartość pliku manifestu po aktualizacji: