Rysowanie palcem po ekranie
Spis treści
Cele
Tym razem stworzymy aplikację z bardziej skomplikowanym, wielowarstwowym interfejsem użytkownika. Sama aplikacja będzie umożliwiała nam rysowanie poprzez przesuwanie palcem po ekranie. Będziemy mieli również możliwość zmiany grubości linii oraz wyboru kolorów. Pomimo, iż brzmi to skomplikowanie, to w istocie jest bardzo proste. A więc do dzieła!
Rysowanie palcem po ekranie
Rozpoczęcie pracy
Wejdźmy na stronę http://appinventor.mit.edu i wybierzmy Create, by uruchomić App Inventor. Następnie przejdźmy do zakładki My Projects (1), gdzie znajdziemy wszystkie nasze projekty - wystarczy tylko zalogować się na odpowiednie konto Google. W celu rozpoczęcia pracy nad nowym projektem kliknijmy na Start new project (2), i wpiszmy w oknie jego nazwę, np. Rysowanie.
Nastąpi teraz automatyczne przejście do okna budowy aplikacji.
Projektowanie interfejsu
Na początek przejdźmy do okna Properties i dla komponentu Screen1, w polu Screen Orientation (1) wybierzmy Portrait. Dzięki temu nasz ekran zawsze będzie wyświetlany pionowo, zaś aplikacja będzie pracowała tylko w takiej orientacji ekranu. Dodatkowo, w polu Title wpiszmy tytuł naszego bieżącego komponentu (2). Nazwijmy go Rysowanie.
W tym momencie omówimy trzy komponenty, które znajdziemy w obszarze Palette, w grupie Layout. Komponenty te będą nam potrzebne, by właściwie rozmieścić na ekranie urządzenia mobilnego pozostałe elementy. Znajdziemy tam (1):
- HorizontalArrangement (rozmieść poziomo)
- TableArrangement (rozmieść w tabeli)
- VerticalArrangement (rozmieść pionowo)
Podczas budowy poprzednich aplikacji mogliśmy zauważyć, że wszystkie elementy układały się na ekranie jeden pod drugim. Teraz przy pomocy trzech powyższych komponentów będziemy mogli dowolnie sterować ułożeniem pozostałych komponentów. Co więcej, komponenty grupy Layout można zagnieżdżać, czyli umieszczać warstwowo - jeden wewnątrz drugiego. Możemy więc wstawić jeden jeden Vertical Arrangement, a potem w trzech kolejnych wierszach wstawić HorizontalArrangement. Przyjrzyjmy się teraz na następnej ilustracji, jak powinien wyglądać kompletny interfejs naszej aplikacji. Następnie, krok po kroku, omówimy proces budowy całego interfejsu.
Schemat interfejsu użytkownika:
1. VerticalArrangement1
ten komponent wypełnia cały ekran [Fill parent] a w nim pionowo (jeden pod drugim) są umieszczone:
1.1 Canvas
1.2 HorizontalArrangement1
w tym komponencie poziomo (jeden obok drugiego od lewej do prawej) znajdują się kolory do wyboru:
1.2.A Czarny 1.2.B Niebieski 1.2.C Czerwony 1.2.D Zielony 1.2.E Żółty 1.2.F Biały
1.3 HorizontalArrangement2
tutaj poziomo (czyli jeden obok drugiego, od lewej do prawej) ułożone są:
1.3.A Przycisk Czyść 1.3.B VerticalArrangement2 1.3.C Przycisk Zdjęcia
a w nim pionowo:
1.3.B.1 Label – etykieta wyświetlająca tekst „szerokość”
1.3.B.2 Slider1 – suwak ustawiający szerokość linii
Zaczniemy oczywiście od pierwszego komponentu, czyli VerticalArrangement (1). Umieśćmy go na ekranie i zmieńmy jego właściwości tak, by odziedziczył rozmiary po nadrzędnym komponencie Screen1, dzięki czemu rozciągnie się na cały ekran aplikacji (2):
- Width (szerokośc) - Fill Parent
- Height (wysokość) - Fill Parent
Następnie wewnątrz elementu VerticalArrangement1 umieśćmy komponent Canvas (1). Jeżeli Canvas został umieszczony poprawnie, czyli jako komponent podrzędny w stosunku do VerticalArrangement1, będziemy mogli to zauważyć w oknie Components (2). Dla tego komponentu ustawimy jeszcze szerokość jako Fill Parent (3). Wysokości na razie nie zmieniajmy - w następnym kroku wyjaśnimy, dlaczego.
Teraz wstawmy dwa komponenty HorizontalArrangement (1) jeden pod drugim. Należy zwrócić uwagę, by były one właściwie rozmieszczone w stosunku do pozostałych komponentów, tak, jak na poniższej ilustracji.
Po dodaniu dwóch komponentów HorizontalArrangement wróćmy do komponentu Canvas i ustawmy jego wysokość (Height) na Fill Parent. Dzięki temu obszar Canvas wypełni pozostałą brakującą przestrzeń w wysokości ekranu i sam przyjmie odpowiednią wartość. Teraz musimy ustawić atrybuty szerokości i wysokości naszych dwóch pozostałych komponentów, czyli elementów HorizontalArrangement. Dla pierwszego z nich (2), czyli tego, który znajduje się bezpośrednio pod komponentem Canvas (1), w oknie Properties ustawmy Width: Fill Parent oraz Height: 50 pikseli. Dla kolejnego komponentu HorizontalArrangement (3) ustawmy Width: Fill Parent oraz Height: Automatic. Jeżeli poprawnie ustawiliśmy te wartości, w oknie Viewer powinniśmy zobaczyć takie ułożenie komponentów, jak na ilustracji obok.
Teraz zaznaczmy komponent Screen1 (1) i zmieńmy kolor jego (BackgroundColor) na szary, czyli (Gray ) (2). Dzięki temu tło całej aplikacji będzie szare.
Powtórzmy ten sam krok dla komponentu Canvas1 (1), z tą różnicą, że tutaj ustawimy kolor tła na jasnoszary (LightGray) (2).
Teraz dodajmy przyciski, którymi będziemy ustawiali kolory. Jak zauważyliśmy wcześniej, łącznie będzie 6 kolorów, potrzebujemy więc 6 przycisków.
W celu dodania pierwszego przycisku wybierzmy komponent Button (1) i przeciągnijmy go na nasz pierwszy HorizontalArrangement (2). Prawidłowo wstawiony przycisk będzie podrzędny względem komponentu HorizontalArrangement1, co możemy sprawdzić w oknie Components (3).
Zaraz po dodaniu przycisk będzie wyglądał tak, jak widzimy na ilustracji (4). Musimy więc odpowiednio go zmodyfikować. Dla każdego przycisku, w jego cechach powinniśmy ustawić BackgroundColor: [kolor odpowiedni dla przycisku] (5), Shape: oval (6), Text: [to pole zostawiamy puste] (7), Width: Automatic (8), Height: Fill parent (9). Warto pamiętać również o zmianie nazw przycisków na takie, które będą odpowiadały ich kolorom (3).
Dodajmy i skonfigurujmy teraz samodzielnie następujące przyciski:
- czarny
- niebieski
- czerwony
- zielony
- żółty
- biały
Po ich dodaniu musimy zmodyfikować dla każdego z nich parametr Width. W każdym przycisku ustawmy tam Fill Parent, dzięki czemu wszystkie będą miały jednakową szerokość.
Po poprawnym wykonaniu wszystkich kroków nasze przyciski służące do wyboru kolorów powinny wyglądać tak, jak na poniższej ilustracji. Teraz zajmijmy się dodaniem komponentów do drugiego, dotychczas pustego, HorizontalArrangement2.
Wstawmy więc:
- Button z grupy User Interface (1)
- VerticalArrangement z grupy Layout (2)
W celu ułożenia dwóch przycisków (nr 3 i 4 na powyższej ilustracji) jeden pod drugim, musimy umieścić je w komponencie VerticalArrangement.
- ImagePicker z grupy Media (3) - ten element pozwala na dostęp do galerii zdjęć urządzenia mobilnego. Przy pomocy tego komponentu będziemy mogli wybrać jedno ze zdjęć z naszego urządzenia i ustawić je jako tło rysunków.
- Button z grupy User Interface - element, który wykorzystamy jako przycisk zapisujący zdjęcia.
Wstawmy zatem: Dzięki temu, że wstawiliśmy komponent VerticalArrangement, możemy pionowo umieścić w nim teraz dodatkowe elementy, których będziemy potrzebowali w naszej aplikacji. Zrobimy to dokładnie w taki sam sposób, w jaki przed chwilą wstawiliśmy przyciski Zdjęcia oraz Zapisz.
- Label (1) - posłuży nam do poinformowania użytkownika, jaką rolę pełni slider
- Slider (2) - ten komponent pozwoli nam wybrać wartość (w tym przypadku grubość linii), poprzez przesuwanie palcem wskaźnika
Zajmiemy się teraz ustawieniem cech obu komponentów, które znajdują się w środku VerticalArrangement1, czyli Label1 oraz Slider1.
Zacznijmy od Label1. Zaznaczmy ten komponent i w oknie Properties w polu Text wpiszmy szerokość (1). W polu TextAllingement (wyrównanie tekstu) ustawmy wartość center (2), zaś w polu Width: Fill Parent (3).
Następnie zaznaczmy Slider1 i tam ustawmy:
- ColorLeft i ColorRight: Orange (1)
- MaxValue: 1 (2)
- MinValue: 10 (3)
- ThumbPosition: 3 (4)
- Width: Fill parent (5)
Komponent Slider1 wykorzystamy do sterowania szerokością rysowanych linii. Wartości Max i MinValue definiują wartości graniczne, zaś ThumbPosition wyznacza pozycję początkową. Zatem będziemy mogli zmieniać grubość kreski od 1 do 10 pikseli, natomiast domyślna grubość linii będzie wynosiła 3 piksele. W następnym kroku zajmiemy się elementem ImagePicker1. Tutaj musimy wykonać tylko dwie czynności: zmienić nazwę na ZDJĘCIA (1) oraz ustawić szerokość na Fill Parent (2).
Kolejnym krokiem w budowie naszego interfejsu będzie modyfikacja przycisku odpowiadającego za czyszczenie ekranu. W polu Components zmieńmy jego nazwę w polu Components na Czyść, poprzez kliknięcie przycisku Rename (1). Również we właściwościach zmieńmy wyświetlany tekst na Czyść (2).
Zaprogramowanie aplikacji
Po zakończeniu prac nad budową interfejsu, możemy przejść do stworzenie programu naszej instrukcji. Wbrew pozorom instrukcje, które za chwilę wykonamy, są bardzo proste. Przejdźmy więc teraz do zakładki Blocks. Zaczniemy od ustawienia programu dla przycisków wyboru koloru.
Wydarzenie when[Biały].Click (czyli: po naciśnięciu przycisku Biały) spowoduje uruchomienie aplikacji set[Canvas1].[PaintColor] to kolor biały (czyli: ustaw kolor rysowania komponentu Canvas1 na biały). Od tego momentu wszystko, co narysujemy na ekranie będzie rysowane kolorem białym.
Dla przypomnienia:
Instrukcję when[Biały].Click znajdziemy w grupie poleceń dla obiektu przycisk Biały (1). Podobnie z poleceniem set[Canvas1].[PaintColor] to (2) oraz ustawionym kolorem (3).
Stwórzmy podobne instrukcje dla pozostałych kolorów, by uzyskać rezultat taki, jak na ilustracji obok.
Zaprogramujmy teraz zachowanie przycisk Czyść. W tym celu wybierzmy blok when[Czyść].Click i do środka wstawmy kolejny klocek, czyli call[Canvas1].Clear - a więc po naciśnięciu przycisku Czyść wyczyść obszar Canvas1.
Kolejną funkcją, którą utworzymy, będzie program zmiany grubości linii rysowania. Wstawiamy tutaj when[Slider1].PositionChanged i dalej w środku: set[Canvas1].[LineWidth] to get[thumbPosition], czyli: po przesunięciu wskaźnika Slider1 (blok PositionChange) uruchom akcję: ustaw szerokość rysowania obiektu Canvas1 na wartość wskazywaną przez Slider1 (blok thumbPosition).
Blok Get[thumbPosition] uzyskamy poprzez najechanie wskaźnikiem myszy na [thumbPosition] (1).
Teraz czas na komponent ImagePicker1, który pozwoli nam wybrać z galerii zdjęć naszego telefonu dowolny obraz i ustawić go jako tło naszych rysunków. Wykonanie wydarzenia AfterPicking (po wybraniu zdjęcia), czyli kiedy wybierzemy zdjęcie, wywoła funkcję: ustaw tło Canvas1 jako wybrane zdjęcie [Selection] w ImagePicker1.
Zostały nam już tylko dwie ostatnie instrukcje. Pozwolą nam one wywołać określone akcje w sytuacjach, gdy dotkniemy (narysowanie punktu - pierwsza instrukcja) lub przesuniemy palcem (narysowanie linii - druga instrukcja) po ekranie. W tych instrukcjach chodzi nam jedynie o wywołanie akcji rysowania punktu lub linii, ponieważ pozostałe parametry, takie jak kolor i grubość punkty/linii ustawiliśmy w poprzednich instrukcjach.
Kiedy Canvas1 jest dotknięty (TouchedDown) to narysuj punkt (DrawPoint) w miejscu dotknięcia (współprzędne X i Y).
Kiedy Canvas1 jest przeciągnięty (Dragged) to narysuj linię (DrawLine) od miejsca dotknięcia (współprzędne X1 i Y1, czyli prev) do miejsca zwolnienia palca (współprzędne X1 i Y1, czyli current).
Warto zauważyć, że w obu instrukcjach Wartość XY są względne i odnoszą się do prawego górnego rogu Canvas1, ponieważ to do tego komponentu się odwołują (a nie do całego ekranu).
Podsumowanie
Poznaliśmy bardziej zaawansowane mechanizmy projektowania interfejsu użytkownika - potrafimy już bardziej precyzyjnie sterować wyglądem poszczególnych komponentów. Co więcej, poznaliśmy też możliwości komponentów z obszaru Media i wiemy, jak za ich pośrednictwem uzyskać dostęp do dowolnych elementów graficznych. Nauczyliśmy się również, jak sterować kolorem i grubością rysowanej kreski. To wszystko daje nam dobre podstawy, by uczyć się jeszcze trudniejszych rzeczy