Programowanie urządzeń mobilnych Lista 2 Aktywności i zdarzenia Jak już wiemy, pojedyncza aktywność reprezentuje pojedynczy ekran z interfejsem użytkownika. W zdecydowanej większości przypadków, może poza najprostszymi aplikacjami, składają się one z więcej niż jedna aktywności. Jak zatem dodać kolejną aktywność do naszej aplikacji? Zaczynamy od standardowej aplikacji z jedną pusta aktywnością: "Zerknijmy" na chwile do metody oncreate w pliku AktywnoscGlowna.java: Zwróćmy uwagę na wiersz o numerze 11. Znajdziemy tam sformułowanie, w którym stwierdza się, że obowiązującym dla tego pliku interfejsem jest ten zdefiniowany w zasobie
R.layuot.activity_aktywnosc_glowna, który oczywiście możemy znaleźć w drzewie projektu w węźle res->layout->activity_aktywnosc_glowna.xml (patrz poniżej). Jak wynika z powyższego, każda aktywność składa się z dwóch plików: kodu wykonywalnego.java, oraz pliku opisującego interfejs czyli.xml. Informacje o aktywnościach wchodzących w skład projektu zapisywane są w pliku AndroidManifest.xml: W przypadku powyższym wyraźnie zaznaczono, która z aktywności (na chwilę obecną jest tylko jedna), będzie uruchamiana jako pierwsza, czyli będzie aktywnością główną. Nowa aktywność w aplikacji Aby dodać do aplikacji kolejną aktywność można postąpić w dwójnasób. Można samodzielnie dodać nowe pliki odpowiadające za kod wykonywalny oraz wygląd (czyli.java oraz.xml), można również skorzystać z kreatora, który tę procedurę znacznie uprości. Nowa aktywność przy użyciu kreatora Aby dodać nową aktywność do aplikacji wybieramy menu File->New->Activity, a następnie jeden z typów proponowanych aktywności. Dla celów przykładu wystarczy EmptyActivity:
Dla parametrów jak powyżej, po zakończeniu działa kreatora drzewo projektu zawierać będzie nowy plik AktwynoscDruga.java oraz activity_aktywnosc_druga.xml. Warto zwrócić uwagę, na to, iż w pliku manifest, również pojawił się stosowny wpis:
Nowa aktywność samodzielnie "krok po kroku" Bazując na przykładzie poprzednim możemy spróbować dodać jeszcze jedną aktywność do realizowanej aplikacji - w tym przypadku dodaną samodzielnie - nie w oparciu o kreatora. Najprościej rozpocząć od węzła (w menadżerze projektu) app->java->[nazwa aplikacji], gdzie przy użyciu menu kontekstowego (pod prawym klawiszem) wybierając New->Java Class dodać możemy nowy plik z kodem wykonywalnym aktywności: W kroku kolejnym należy utworzyć nowy layout, który będzie graficznym reprezentantem klasy utworzonej powyżej. Możemy to wykonać również przy użyciu menu kontekstowego np. węzła app- >res->layout wybierając New->Layout resource file: Oczywiście nazwa aktywność może być dowolna (używamy tylko małych liter), lecz warto pamiętać o stosowaniu jednolitego nazewnictwa w całym projekcie (łatwiej wtedy o zachowanie porządku). Mamy zatem plik.java oraz.xml. Przypomnieć tutaj warto, iż plik zawierający kod wykonywalny aktywności musi mieć przypisany odpowiadający mu plik.xml, a nowo utworzona klasa takiego nie posiada:
Przechodząc zatem do edycji pliku TrzeciaAktywnosc.java musimy wykonać dwie rzeczy: 1. Określić klasę AktywnoscTrzecia jako klasę dziedziczącą po klasie Activity (w końcu reprezentować ma ona aktywność) 2. Przeładować metodę oncreate(), w której określić, który z "layoutów" (zasobów plikach.xml), będzie odpowiadał za wygląd aktywności: Nie można oczywiście zapomnieć o dodaniu nowo utworzonej aktywności do pliku manifestu: Zdarzenia w aktywnościach Oczywiście w każdej aplikacja pracującej pod kontrolą systemu Android mamy do czynienia z bardzo dużą liczbą równych zdarzeń które możemy obsługiwać z poziomu programu, jednak jednym z podstawowych jest zdarzenie, które odpowiada kliknięciu (dotknięciu) przycisku. W tym celu do aktywności głównej przykładowej aplikacji dodać można przycisk (Button), a nawet dwa, gdyż realizowany w tej części przykład zawiera trze aktywności. Dla czytelności działania aplikacji warto oznaczyć je stosowanym komentarzem:
Warto zwrócić uwagę na identyfikatory (@+id) obu dodanych przycisków (wiersze 17 oraz 28). Domyślne identyfikatory o nazwa button1 lub button2 warto zmienić na własne, wskazujące na funkcje jakie dany przycisk na docelowo realizować (warto stosować jednolite nazewnictwo w projekcie). Oczywiście tak dodane przyciski nie będą reagować, na żadne akcje ze strony użytkownika, gdyż nie podpięto do nich jak dotąd obsługi żadnego zdarzenia. W tym celu dodajmy do definicji przycisku w pliku.xml (w tym przypadku activity_aktywnosc_glowna.xml) wiersz, w którym określlimy nazwę metody, jaka powinna zostać wykonana w przypadku wystąpienia zdarzenia onclick() na rzecz poszczególnych przycisków - patrz wiersz 22 poniżej. Oczywiście czynność tę powtarzamy dla przycisku drugiego. Nietrudno się domyślić, iż zapis zastosowany powyżej nie jest wystarczający - koniecznym jest jeszcze napisanie metod, do których się tam odwołujemy, co oczywiście robimy w pliku AktywnoscGlowna.java. Powyżej zaprezentowano treść tych metod - w obu przypadkach są zasadniczo identyczne, więc wystarczy omówić tylko pierwszą z nich. Metoda jako parametr otrzymuje obiekt klasy View (wiersz
15) - jej parametrem aktualnym w momencie wywołania będzie "kliknięty" przycisk. Wewnątrz metody wykorzystamy metodę startactivity, która korzystając z tzw. intencji (ang. Intent), pozwala uruchomić inną aktywność. Tzw. intencje, to jedne z podstawowych komponentów wchodzących w skład aplikacji dla systemu Android. Jest to podstawowy mechanizm służący do wymiany informacji pomiędzy aktywnościami lub innymi komponentami. Jeśli Android Studio oznaczy np. klase View lub Intent jako nieznaną (domyślnie czerwonym kolorem tekstu) należy zaimportować do pliku.java odpowiedni biblioteki (najlepiej postępować zgodnie z sugestiami Android Studio dostępnymi jako menu kontekstowe dla fragmentu oznaczonego jako nieznany tekst). Przekazywanie wartości między aktywnościami Dla zobrazowania zagadnienia posłużyć się można wcześniej przygotowanym szkieletem aplikacji, składającej się z 3 aktywności, z których pierwsza będzie wywoływała pozostałe. Jak zaprezentowano powyżej aktywność główna składa się z pola edycyjnego typu EditText (@+id/poleedycyjne - wiersz 17), oraz dwóch przycisków typu Button (@+id/buttonoknopierwsze - wiersz 27 oraz @+id/buttonoknodrugie - wiersz 37). Warto zauważyć, że w przypadku obu przycisków jako metodę obsługującą zdarzenie onclick wskazano metodę o nazwie ObslugaPrzyciskow co może, aczkolwiek wcale nie musi oznaczać, że oba przyciski będą realizowały takie same funkcjonalności. Jaki kod zatem zawiera metoda ObslugaPrzyciskow, którą umieszczamy oczywiście w pliku AktywnoscPierwsza.java?
1. Wiersz 19 - zmienna pomocnicza typu napisowego - będzie potrzebna w wierszy kolejnym 2. Wiersz 20 - korzystamy z faktu, iż wiemy, który z elementów interfejsu jest źródłem wywołania metody, gdyż informacja ta zawarta jest w parametrze wywołania metody czyli w obiekcie klasy widok, dzięki temu możemy np. sprawdzić jaki napis był na nim umieszczony 3. Wiersz 21 - sprawdzamy, czy wyizolowany w punkcie poprzednim napis odpowiada przyciskowi pierwszemu czy też drugiemu. Jeśli był to przycisk pierwszy wykonujemy operacje w zakresie od wiersza 23 do 27. 4. Wiersz 23 - nowy, tym razem nie anonimowy (patrz wiersz 31 oraz wcześniejsze przykłady) reprezentant klasy Intent. 5. Wiersz 24 - reprezentant pola edycyjnego umieszczonego na aktywności głównej 6. Wiersz 25 - napis, do którego zostanie wpisany ciąg wprowadzony przez użytkownika do pola edycyjnego. 7. Wiersz 26 - wewnątrz intencji z wiersza 23 umieszczamy wartość przechowywaną w napisie Komunikat i nadajemy mu identyfikator PrzesylanyKomunikat 8. Wiersz 27 - uruchomienie aktywności AktywnoscDruga w oparciu o wcześniej przygotowaną Intencję 9. Wiersz 31 - wywołanie aktywności AktywnoscTrzecia przy użyciu intencji anonimowej. Ostatnim krokiem jest przygotowania aktywności AktywnoscDruga do przetworzenie przekazanych danych. Zakładamy, że wyposażona jest ona w pole typu label, na którym wyświetlony zostanie ciąg znaków wpisany przez użytkownika w aktywności głównej. Kod meto oncreate() w pliku AktywnoscDruga.java ma postać: 1. Wiersz 13 - obiekt o nazwie WyswietlaczKomunikatu, który będzie reprezentantem pola typu TexView zdefiniowanego w pliku.xml
2. Wiersz 14 - tekst wyświetlany przez WyswietlaczKomunikatu zostaje ustawiony w oparciu o wartość identyfikatora o nazwie PrzesłanyKomunikat, kótra zostaje pobrana z obiektu Intent (ustawiona została przed wywołaniem aktywności). Rysowanie po powierzchni aktywności Jeśli zajdzie potrzeba programowego narysowania elementów interfejsu użytkownika, wyświetlanych przez aktywność, można posłużyć się różnymi rozwiązaniami. Jednym z najprostszych jest podmiana obiektu reprezentującego domyślny zasób.xml z definicją wyglądu aktywności na własny, zupełnie inny obiekt klasy View (dziedziczące po niej gwoli ścisłości). Przykład takiego rozwiązania zaprezentowano poniżej: 1. Wiersz 44 - podmiana domyślnego kontekstu graficznego (domyślnie była to activity_aktywnosc_glowna). 2. Wiersz 14 - definicja własnej klasy dziedziczącej po klasie View. 3. Wiersz 17 - jawne wywołanie konstruktora klasy przodka czyli View. 4. Wiersz 20 - przeładowanie metody ondraw() dla bieżącego kontekstu rysowania. 5. Wiersz 21 - wywołanie metody ondraw() na rzecz klasy przodka. 6. Wiersz 23 i 24 - ustalenie parametrów pracy pisaka. 7. Wiersz 37 - wymuszenie odświeżenia okna aktywności.
Zadanie 1 (15 pkt) Przygotuj aplikację dla Android, w której zaprezentujesz metody klasy Canvas (oczywiście przykłady nie mogą się ograniczać do podstawowych wielokątów - są przecież wypełnienia, teksty itp). Każdy z przykładów ma mieć własną aktywność, która powinna pozwolić ustalić użytkownikowi parametry rysowania danego obiektu, np. wymiary i kolor wypełnienia prostokąta. Ostateczne rysowanie przykładów powinno być realizowane przez jedną aktywność, która będzie sterowana przez parametry uruchomieniowe ustalane przez aktywności z poszczególnymi przykładami.