Interaktywna zmiana koloru tła aplikacji (ćwiczenie 3)

W ramach ćwiczeń związanych z tworzeniem programów na urządzenia mobilne pracujące pod kontrolą systemu operacyjnego Android często wykorzystywanym przykładem jest aplikacja umożliwiająca zmianę tła wyświetlanego na ekranie urządzenia. Poniższa instrukcja bazuje na materiałach wykorzystywanych w Internecie i prowadzi Użytkowników Ćwiczenia numer 3 od dostępu do przycisku w kodzie Java, poprzez uzyskiwanie koloru tła ekranu, ustawiania tego koloru i wykrywania naciśnięć przycisków, aby zmienić kolor tła.

Podstawowym celem ćwiczenia jest stworzenie aplikacji na Androida, w której kolor tła aplikacji może być zmieniany przez Użytkownika z koloru czerwonego na niebieski o odwrotnie. Kolor tła aplikacji zmieni się za każdym razem, gdy klikniemy przycisk znajdujący się na środku ekranu. Jest to bardzo prosta aplikacja, ale nauczy podstawowych kroków programowania wizualnego.

Tworzenie nowego projektu Android

Rozpoczynamy od utworzenia Projektu. Najpierw wybieramy polecenie „Utwórz nowy projekt”. Jeśli Android Studio już działa, należy wybrać polecenie File->New->New Project z górnego menu, jak pokazano na poniżym rysunku:


Rysunek 1. Tworzenie nowego projektu w Android Studio

Nazwa aplikacji może być dowolna, lecz w ramach ćwiczenia nadajmy jej nazwę „Lighthead app”, tak jak to pokazano na rysunku 2.


Rysunek 2. Nadanie nazwy aplikacji

Następnie należy wybrać opcję aby aplikacja była kompatybilna z telefonami i tabletami z określoną wersją systemu Android (przykładowo 4.0.3 - Ice Cream Sandwich) lub nowszym:

 
Rysunek 3. Wybór kompatybilności aplikacji (wersji systemu Android)

Będziemy mieli prostą zawartość ekranu, dlatego wybieramy opcję „Pusta aktywność” w następnym oknie dialogowym:


Rysunek 4. Wybór układu ("layoutu") ekranu

Na koniec pozostawiamy nazwę aktywności jako „MainActivity”, a następnie klikamy klawisz „Zakończ”, aby utworzyć odpowiednie pliki projektu:


Rysunek 5. Ustawienia końcowe

Po pomyślnym utworzeniu projektu pojawi się domyślny widok Android Studio, w którym środkowy panel pokaże plik „MainActivity.java”, jak pokazano na poniższym rysunku:


Rysunek 6. Widok domyślny w Android Studio

Opracowywanie interfejsu użytkownika

Otwórzmy plik układu interfejsu użytkownika activity_main.xml, w którym umieścimy przycisk na ekranie. Jak widać na powyższym rysunku, lewy panel pokazuje foldery i pliki naszego projektu. Upewniamy się, że typ widoku to Android i wybieramy foldery res->layout, a następnie klikamy dwukrotnie plik activity_main.xml, jak pokazano na rysunku 7.


Rysunek 7. Znajdowanie pliku activity_main.xml w eksploratorze projektów

Po otwarciu pliku activity_main.xml układ, który zawiera, zostanie wyświetlony w środkowym okienku, jak pokazano na rysunku 8. Ten plik i inne pliki xml zawierają informacje o układzie aplikacji na Androida w Android Studio.

W rzeczywistości pliki xml są wykorzystywane nie tylko w tworzeniu aplikacji na Androida, ale także w innych obszarach programowania. Pliki xml są dobre do wyrażania relacji między różnymi podmiotami w sposób hierarchiczny, dlatego są dobrym wyborem do wykorzystania w projektowaniu układu.

Pliki xml to pliki tekstowe, ale Android Studio interpretuje je jako graficzną prezentację ekranu, o ile mają prawidłowy format. Możemy również wyświetlić reprezentację pliku tekstowego activity_main.xml w Android Studio, wybierając kartę Tekst, jak wskazuje strzałka na rysunku 8.


Rysunek 8. Wyświetlanie activity_main w Android Studio

Po wybraniu karty Tekst format tekstowy pliku activity_main.xml jest wyświetlany w środkowym okienku w następujący sposób:


Rysunek 9. activity_main.xml plik w reprezentacji tekstowej

Nie należy się stresować skomplikowaną zawartością tego pliku. Większość operacji związanych z układem wykonamy wizualnie. Użyjemy tej reprezentacji tekstowej tylko w szczególnych przypadkach. Jednak dobrą praktyką jest śledzenie zawartości pliku xml podczas projektowania układów aplikacji. Na powyższym rysunku widzimy, że nasz układ składa się ze struktury RelativeLayout, która zaczyna się od wiersza <RelativeLayout… i kończy na </RelativeLayout>. Wewnątrz tego układu mamy komponent TextView. Innymi słowy, składnik TextView istnieje wewnątrz składnika RelativeLayout. Zobaczmy teraz, jak ogólnie zbudowany jest graficzny interfejs użytkownika aplikacji na Androida przy użyciu tych komponentów.

W systemie Android wszystkie obiekty graficznego interfejsu użytkownika (GUI) (widżety, układy, obiekty obrazów itp.) pochodzą z klasy View biblioteki GUI. Podstawową hierarchię klas GUI pokazano na rysunku 10.


Rysunek 10. Podstawowa hierarchia komponentów GUI

Komponenty GUI aplikacji na Androida mają następujące podstawowe właściwości: 

  • Ponieważ wszystkie obiekty GUI pochodzą z klasy View, te obiekty GUI są również nazywane "widokami" w programowaniu w systemie Android.
  • Klasy podrzędne ViewGroup RelativeLayout, LinearLayout, AbsoluteLayout i GridLayout są specjalnymi widokami, które mogą zawierać inne widoki i komponenty. Są one używane do kształtowania widoku rkeanu według własnego uznania.
  • Interfejs graficzny systemu Android powinien składać się z co najmniej jednej klasy układu. Na przykład nasz plik activity_main.xml ma układ RelativeLayout, tak jak to pokazano na rysunku 9.
  • Możemy zbudować dowolne GUI, używając podklas klasy View pokazanej na rysunku 10.

Programiści preferują różne strategie kształtowania GUI swojej aplikacji. Jeszcze do niedawna RelativeLayout zapewniało większą elastyczność, dzięki czemu było łatwiejszą w użyciu. Podstawową właściwością RelativeLayout jest to, że wszystkie obiekty graficznego interfejsu użytkownika (GUI) są pozycjonowane względem siebie.

W każdym razie kontynuujmy rozwijanie naszej aplikacji z czerwonym/niebieskim tłem aplikacji. Przechodzimy do widoku projektu pliku activity_main.xml, jak na rysunku 8, abyśmy mogli wizualnie zaprojektować GUI.

Przede wszystkim usuwamy domyślny widok tekstu „Hello World”, klikając go prawym przyciskiem myszy i wybierając „Usuń”, jak pokazano poniżej:


Rysunek 11. Usuwanie domyślnego widoku tekstu „Witaj świecie”

Po usunięciu domyślnego TextView, znajdujemy widżet Button z palety obiektów, a następnie przeciągamy i "upuszczamy" go na środku GUI za pomocą linii prowadzących, jak pokazano na rysunku 12.


Rysunek 12. Dodanie widżetu przycisku w środku interfejsu użytkownika

Kiedy dodajemy widżet do GUI, jest on ciągle w trybie "zaznaczany", i w tym trybie jego właściwości można przeglądać z prawego panelu, jak pokazano na rysunku 13. Podstawowe właściwości przycisku są pokazane w tym panelu. Możemy jednak zobaczyć pełną listę właściwości, klikając Wyświetl wszystkie właściwości (można je zobaczyć po przewinięciu w dół), jak pokazano na rysunku 14.

Przechodzimy do panelu podstawowych właściwości pokazanych wewnątrz prostokąta na rysunku 13. W tym panelu jedną z najważniejszych właściwości dostępu do przycisku jest jego identyfikator. Dostęp do wszystkich obiektów GUI aplikacji na Androida uzyskuje się poprzez ich identyfikatory w części kodującej (kodu programu).


Rysunek 13. Podstawowe właściwości widżetu przycisku


Rysunek 14. Przełączanie do wszystkich właściwości widżetu przycisku

W aplikacji opracowanej w ramach ćwiczenia domyślny identyfikator widżetu przycisku jest ustawiany jako przycisk przez Android Studio. Możemy to zmienić, klikając pole ID i podmieniając tekst przycisku.

Następne dwa pola odnoszą się do właściwości szerokości i wysokości układu widżetu przycisku. Ich ustawienia określają szerokość i wysokość obiektu przycisku w GUI. Są one domyślnie ustawione jako wrap_content. Oznacza to, że szerokość i wysokość przycisku zostaną dostosowane tak, aby zawijać (zakrywać) tekst zapisany wewnątrz przycisku (tj. etykietę przycisku). Inną dostępną opcją dla tych parametrów jest match_parent, jak pokazano na rysunku 15. Jeśli ta opcja zostanie wybrana, odpowiednia właściwość (szerokość lub wysokość) będzie równa szerokości lub wysokości kontenera nadrzędnego (czyli RelativeLayout zakrywającego cały ekran w tym przykładzie).


Rysunek 15. Alternatywy dla parametrów layout_width i layout_height

Ponieważ nie chcemy, aby przycisk miał szerokość lub wysokość wypełniającą całe GUI, musimy pozostawić te parametry z wartością wrap_content.

W naszej aplikacji przycisk ma zmieniać kolor tła ekranu, dlatego dobrze jest odpowiednio zmienić etykietę przycisku. Etykieta przycisku (tekst na przycisku) to domyślnie Button. Zmieńmy to na „Zmień!”  (Change), tak jak to pokazano na rysunku 16.


Rysunek 16. Zmiana etykiety przycisku

Pisanie głównego kodu aplikacji

Ponieważ nie potrzebujemy żadnego innego widżetu w GUI, możemy teraz kontynuować programowanie aplikacji. Zawartość programu umieszczona jest w pliku MainActivity.java. Aby otworzyć ten plik, przechodzimy do eksploratora projektów w Android Studio, a następnie klikamy dwukrotnie MainActivity znajdujący się pod java->com…..lightheadapp, jak pokazano na poniższym rysunku:


Rysunek 17. Otwieranie pliku MainActivity.java w Android Studio


Rysunek 18. Domyślny plik MainActivity.java

Pokazany powyżej plik MainActivity.java jest domyślnym plikiem generowanym przez Android Studio. Niektóre wiersze kodu są domyślnie ukryte, jak pokazano przez kropki (…) w wierszu importu. Można otworzyć te kody, klikając kropki (…) tak, jak pokazano poniżej:

 
Rysunek 19. Domyślny plik MainActivity.java po otwarciu ukrytych linii kodu programu

Przeanalizujmy domyślny kod MainActivity.java linia po linii:

  • Pierwsza linia to definicja pakietu, jak w zwykłym kodzie Java. Pokazuje, do którego pakietu należy ten plik.
  • Kolejne dwie linie to linie importu, które importują wymagane biblioteki. W naszym pliku importowane są biblioteki AppCompatActivity i Bundle. Zawierają podstawowe metody interakcji użytkownika i przekazywania danych między różnymi aktywnościami.
  • Następna linia deklaruje klasę MainActivity, która rozszerza klasę AppCompatActivity. To jest jak definicja klasy w Javie. Podobnie jak w Javie, nazwa klasy w Androidzie powinna być zgodna z nazwą pliku .java. W tym przypadku plik to MainActivity.java, dlatego nazwa klasy to MainActivity.
  • Następnie domyślnie umieszczane jest polecenie @override. Służy do poinformowania kompilatora, że bieżąca klasa zastąpi wszelkie istniejące nadklasy.
  • Szósta linia kodu definiuje metodę o nazwie onCreate(). Wszystkie działania rozpoczyna się sekwencją wywołań metod. Metoda onCreate() jest pierwszym z tych wywołań.
  • Następna linia, super.onCreate(savedInstanceState);, mówi, że nasz kod zostanie wykonany oprócz istniejącego kodu (jeśli istnieje) klasy nadrzędnej.
  • W ostatnim wierszu metoda setContentView() ustawia zawartość aktywności ze źródła układu. Ustawiliśmy układ naszej aplikacji w pliku activity_main.xml. Android uzyskuje dostęp do wszystkich zasobów za pośrednictwem klasy pomocniczej o nazwie „R”. Klasa R to specjalna klasa, która umożliwia systemowi Android korzystanie z zasobów w prostszy sposób w porównaniu z dostępem za pośrednictwem ścieżek plików. Argumentem metody setContentView() jest R.layout.activity_main, co oznacza „ustaw zawartość aktywności na układ znajdujący się w activity_main.xml”.

Activity to klasa, która zarządza interfejsem użytkownika i interakcją aplikacji z użytkownikiem. Po uruchomieniu działanie obiektu tej klasy może istnieć w różnych stanach, jak pokazano na rysunku 20.


Rysunek 20. Kilka faz działania

Jak widać na powyższym rysunku, aktywność może mieć kilka faz. Te fazy zależą od samej aktywności oraz systemu operacyjnego Android. Na przykład, jeśli inna aktywność wymaga dużej ilości pamięci, bieżąca aktywność może zostać wstrzymana (onPause()), ponieważ Android daje pierwszeństwo innej aktywności.

W pliku MainActivity.java aplikacji przy pierwszym utworzeniu aktywności wywoływana jest metoda onCreate(). Cała konfiguracja statyczna odbywa się w ramach tej metody.

Jeśli uruchomimy naszą aplikację na tym etapie, powinniśmy zobaczyć zaprojektowany przez nas widok ekranu. Możemy go uruchomić w symulatorze, naciskając przycisk „Uruchom” i wybierając emulator, na którym działa aplikacja, pokazano na rysunku 21.

 
Rysunek 21. Aplikacja w emulatorze

Kiedy klikniemy Zmień! przycisk, na tym etapie nic się nie dzieje, ponieważ nie napisaliśmy jeszcze kodu obsługującego kliknięcia przycisku. Zakodujmy niezbędne operacje, aby zmienić kolor tła za pomocą kliknięć przycisku, tak jak zamierzamy zrobić dla tej aplikacji.

Aby stale sprawdzać przycisk, aplikacja musi „nasłuchiwać” przycisku. Dlatego musimy stworzyć metodę nasłuchiwania przycisku i wywołać ją przy pierwszym uruchomieniu działania. Możemy nadać dowolną nazwę metodzie nasłuchiwania przycisków, takiej jak myButtonListenerMethod(). W tej metodzie musimy znaleźć widżet przycisku za pomocą wspomnianej wcześniej klasy R i utworzyć obiekt przycisku, aby uzyskać dostęp do przycisku. Przedstawiono to w kodzie 1.


Kod 1.

Możemy teraz uzyskać dostęp do przycisku za pomocą obiektu przycisku utworzonego przez wiersz Button button=(Button) findViewById(R.id.button). Metoda findViewById() wyszukuje widoki (widżety, układy itp.) przy użyciu ich identyfikatorów. Identyfikator „button” nadaliśmy naszemu widżetowi przycisku podczas projektowania layoutu. W związku z tym uzyskaliśmy do niego dostęp za pomocą klasy R jako przycisku R.id.

W Android SDK istnieje inna specjalna metoda o nazwie setOnClickListener(). Ta metoda nieustannie nasłuchuje kliknięć w przycisk. Wszystko, co zostanie wykonane, gdy kliknięcie przycisku powinno znajdować się w tej metodzie. Ta metoda jest stosowana do przycisku, którego chcemy odsłuchać, w następujący sposób:


Kod 2.

W powyższym kodzie:

  • Nowa funkcja onClickListener jest tworzona przez nową funkcję View.OnClickListener(), a następnie ten obiekt jest argumentem metody setOnClickListener() , która jest stosowana do obiektu przycisku.
  • Następnie nadpisuje odbiorniki superklasy dyrektywą @Override (w naszym przykładzie nie ma odbiorników superklasy, ta dyrektywa jest automatycznie generowana przez Android Studio).
  • Na koniec po kliknięciu przycisku wywoływana jest metoda o nazwie onClick().

Wszystkie wiersze kodu, które zostaną uruchomione po kliknięciu przycisku, zostaną umieszczone w metodzie onClick(View v).

Naszym celem jest zmiana koloru tła z czerwonego na niebieski i odwrotnie po kliknięciu przycisku. W pliku activity_main.xml widzieliśmy, że nasz GUI ma element RelativeLayout jako główny układ wypełniający ekran. Dzięki temu możemy uzyskać dostęp do tła za pomocą następującego kodu:


Kod 3.

W tym kodzie wygenerowaliśmy obiekt RelativeLayout o nazwie bgElement, z którego możemy uzyskać dostęp do wszystkich właściwości tła aplikacji.

Teraz musimy sprawdzić kolor bgElement. Dzieje się tak, ponieważ zmienimy jego kolor zgodnie z jego aktualnym kolorem. Jeśli teraz jest czerwony, przycisk zmieni kolor na niebieski. Jeśli teraz jest niebieski, kliknięcie przycisku zmieni kolor na czerwony.


Kod 4.

W tym kodzie kolor tła układu aplikacji jest pobierany przez bgElement.getBackground()).getColor(); a następnie konwertowane na typ ColorDrawable, który wyraża kolor jako liczbę całkowitą. Następnie ta wartość całkowita jest przypisywana do zmiennej color. W skrócie kolor tła będzie wyrażony w zmiennej o nazwie color jako liczba całkowita.

Wykorzystamy teraz oświadczenie dotyczące podejmowania decyzji, aby zmienić kolor, takie jak:
Jeśli kolor jest czerwony, zmień na niebieski; w przeciwnym razie (= jeśli kolor jest niebieski) zmień na czerwony.
Możemy to zrobić za pomocą następującego kodu: 


Kod 5.

W Android SDK istnieje specjalna klasa o nazwie Color służąca do wykonywania operacji związanych z kolorami. Wyrażenia Color.RED i Color.BLUE reprezentują wartości całkowite odpowiadające odpowiednio kolorowi czerwonemu i niebieskiemu. Dlatego zmienna color, która zawiera liczby całkowite odpowiadające kolorowi tła, będzie porównywana z wartością całkowitą koloru red przez wyrażenie color == Color.RED. Jeśli są równe, oznacza to, że tło jest aktualnie czerwone i zmieni się na niebieskie po kliknięciu przycisku. W przeciwnym razie tło jest obecnie niebieskie i zmieni się na czerwone, gdy użytkownik kliknie przycisk.

Łącząc wszystkie te linie kodu, dochodzimy do metody detektora przycisku pokazanej w kodzie 6.


Kod 6.


Należy zwrócić uwagę, że możemy użyć instrukcji if-else bez nawiasów klamrowych, ponieważ w ich blokach znajdują się tylko jednowierszowe kody.


Teraz musimy wywołać tę metodę nasłuchiwania przycisku, gdy aktywność jest tworzona po raz pierwszy. Dlatego musimy wywołać go wewnątrz metody onCreate() w następujący sposób:

Kod 7.

Jednak jeszcze nie skończyliśmy, ponieważ tło jest domyślnie przezroczyste, gdy aktywność jest tworzona po raz pierwszy. Dlatego musimy ustawić go na czerwony lub niebieski podczas tworzenia. Ustawmy go jako czerwony, ulepszając kod 7 w następujący sposób:


Kod 8.

W tym kodzie tło jest dostępne, a następnie ustawiane jako czerwone na początku aplikacji. Zwróć uwagę, że musimy zdefiniować osobny obiekt bgElement wewnątrz metody onCreate(). Nie możemy użyć bgElement zdefiniowanego w metodzie detektora przycisków. Dzieje się tak, ponieważ wszystkie zmienne i obiekty zadeklarowane w metodzie są poprawne tylko wewnątrz tej metody (nazywanej również zakresem zmiennych). 

Teraz połączmy te wiersze kodu, aby utworzyć nasz kompletny plik MainActivity.java w następujący sposób:


Kod 9.

Tworzenie i uruchamianie aplikacji

Zakończyliśmy zarówno tworzenie układu, jak i kodu plikacji na Androida. Uruchommy go, klikając przycisk Uruchom w Android Studio. Ekran emulatora po uruchomieniu aplikacji pokazano na rysunku 22.

 
Rysunek 22. Aplikacja po uruchomieniu

Gdy klikniemy na Przycisk [Change!], kolor tła zmienia się z czerwonego na niebieski i odwrotnie, jak pokazano na rysunku 23. 


Rysunek 23. Ekran naszej aplikacji po kolejnych kliknięciach przycisków

 


Małe ćwiczenie: Czy możesz zmodyfikować kod, aby dynamicznie zmieniać etykietę przycisku zgodnie z kolorem tła? Jeśli kolor tła zostanie zmieniony na niebieski, tekst przycisku będzie brzmieć Konwertuj na niebieski! w przeciwnym razie Konwertuj na czerwony!


Materiał opracowany na podstawie zasobów dostępnych w Internecie

Komentarze obsługiwane przez CComment