SZCZEGÓŁOWY SPIS TREŚCI
PODZIĘKOWANIA
WPROWADZENIE
Dlaczego warto nauczyć się programowania?
Dlaczego warto programować w języku Java?
Co można znaleźć w tej książce
Jakie narzędzia będę potrzebne?
Zasoby online
Pora zacząć!
nieprawidłowych danych wejściowych
pokazywanie i ukrywanie przycisku Play Again
układu GUI w widoku projektu
komponentów GUI w Android Studio
Obsługiwanie zdarzeń w systemie Android
Uruchamianie aplikacji na emulatorze Androida
Uruchamianie aplikacji na prawdziwym urządzeniu z systemem Android
Przygotowanie urządzenia
Podłączanie własnego urządzenia
Uruchamianie aplikacji na urządzeniu
Ulepszanie środowiska użytkownika
wpisywanej liczby w polu tekstowym
Dodawanie interfejsu słuchacza dla klawisza enter
Jeszcze jeden ostateczny szlif
programistyczne
Zadanie 1: „Toast”-owanie liczby prób
Zadanie 2: zwiększanie atrakcyjności wizualnej
Zadanie 3: tworzenie aplikacji mobilnej MadLibs
UDOSKONALANIE
opcji w systemie Android
elementów do pliku XML
Reagowanie na wybory użytkownika
wyskakującego okna dialogowego dla opcji About
zakresu liczb do odgadnięcia
okna dialogowego, które umożliwia użytkownikowi
Zadania programistyczne
Zadanie 1: zapętlanie pętli
Zadanie 2: odwracanie i szyfrowanie
Zadanie 3: bezpieczna obsługa kluczy za pomocą instrukcji try-catch
7
TWORZENIE ZAAWANSOWANYCH INTERFEJSÓW GUI
Przygotowywanie projektu aplikacji Secret Messages z interfejsem GUI
Projektowanie interfejsu GUI i nazywanie komponentów
Pisanie kodu aplikacji Secret Messages z interfejsem GUI
Tworzenie metody encode()
Pisanie obsługi zdarzenia dla przycisku Encode/Decode
Obsługa nieprawidłowych danych i błędów
nieprawidłowych danych i błędów: część 2
Dodawanie suwaka do interfejsu GUI aplikacji Secret Messages
Łamanie szyfru przy użyciu suwaka
Bonus: Udostępnianie aplikacji w postaci uruchamialnego pliku JAR
Co już umiesz
Zadania programistyczne
1: przenoszenie w górę!
2: przewijanie!
mobilnego interfejsu GUI
Testowanie aplikacji
z widżetem SeekBar
metodą encode()
Uruchamianie aplikacji na emulatorze i urządzeniu z systemem
Bonus: Dostosowywanie przycisku FAB
Tworzenie klasy Bubble
Definiowanie klasy Bubble
Projektowanie metod klasy Bubble
Przechowywanie bąbelków w ArrayList
Dodawanie konstruktora do klasy BubblePanel
Obsługa zdarzeń myszy inicjowanych przez użytkownika
Tworzenie interfejsu słuchacza zdarzeń do wielokrotnego użytku
Obsługiwanie kliknięć i przeciągnięć
Bonus: obsługa zdarzeń MouseWheel
Co już umiesz
Zadania programistyczne
Zadanie 1: wyeliminowanie zbyt małych bąbelków
Zadanie 2: pikselizacja!
DODAWANIE ANIMACJI I WYKRYWANIE KOLIZJI PRZY UŻYCIU
Kopiowanie projektu Java BubbleDraw w celu utworzenia aplikacji BubbleDrawGUI
Zmienianie nazw klasy z metodą main i pliku Java
Dodawanie transparentności
animacji: bąbelki w ruch!
timera
animacji
timera
Rozdmuchiwanie bąbelków: dodawanie losowej prędkości i kierunku
Budowanie interfejsu GUI dla naszej animowanej aplikacji do rysowania
panelu oraz przycisków GUI
Programowanie przycisków Clear oraz Pause/Start
Odbijanie się od ścian dzięki wykrywaniu kolizji
suwaka do kontrolowania prędkości animacji
Tworzenie konstruktora BubbleView()
Przygotowywanie układu do użycia widoku BubbleView
Modyfikowanie klasy Bubble
Rysowanie w systemie Android przy użyciu metody onDraw()
Testowanie aplikacji BubbleDraw przy użyciu stu bąbelków
metody testBubbles()
błędu OnTouchListener
aplikacji BubbleDraw
Wykorzystywanie wątkowej animacji i wielozadaniowości w języku Java
Wykorzystywanie dotyku do rysowania palcem
Wykorzystywanie wielodotykowości do rysowania dziesięcioma palcami naraz!
Testowanie zdarzeń wielodotykowości na urządzeniu Android
ikony aplikacji
niestandardowej ikony aplikacji
Dodawanie niestandardowej ikony aplikacji
Wyświetlanie nowej ikony
Zmienianie nazwy aplikacji
Co już umiesz
Zadania programistyczne
Zadanie 1: łączenie zdarzeń dotknięcia jednym i wieloma
Zadanie 2: łączenie zdarzeń dotknięcia jednym i
DODATEK DEBUGOWANIE I UNIKANIE TYPOWYCH BŁĘDÓW
Pisownia i wielkość liter
Problemy z porównaniami
grupujące
Szybkie rozwiązania w programie Eclipse
Uzupełnianie kodu w Android Studio
Podsumowanie
nika oraz generować liczby losowe. Będziemy pisać własne klasy do realizowania nowych zadań, jak również wykorzystywać klasy dostępne już w języku Java do wykonywania codziennych czynności, takich jak obsługa danych wejściowych, operacje matematyczne i nie tylko.
Zadania programistyczne
Aby utrwalić i przećwiczyć zdobyte umiejętności oraz rozszerzyć swoją wiedzę, wykonaj następujące zadania programistyczne. Jeśli napotkasz problemy, można wejść na stronę internetową tej książki o adresie https://www.nostarch. com/learnjava/, aby pobrać przykładowe rozwiązania lub obejrzeć wideo z instrukcjami krok po kroku w ramach kursu online dostępnego na stronie http:// www.udemy.com/java-the-easy -way/. Rozdział 2 można wypróbować za darmo. Można również użyć kodu BOOKHALFOFF, aby otrzymać 50 procent zniżki na zakup całego kursu.
Zadanie 1: rozszerzanie zakresu
W tym pierwszym zadaniu zmodyfikuj zgadywankę w taki sposób, aby losowała ona liczbę z szerszego zakresu. Aby użytkownik musiał odgadnąć liczbę z przedziału od –100 do 100 zamiast od 1 do 100.
Wskazówka Pomnóż Math.random() przez 200 i odejmij 100 od wyniku.
Pamiętaj o zmodyfikowaniu zarówno instrukcji programistycznej służącej do generowania liczby losowej, jak i przedstawianej użytkownikowi instrukcji z informacją, w jakim przedziale mieści się odgadywana liczba.
Jeśli chcesz ułatwić grę, możesz zmniejszyć przedział od 1 do 10 i zaskoczyć znajomych umiejętnością odgadnięcia sekretnej liczby w maksymalnie czterech podejściach. Przetestuj inne zakresy, np. od 1 do 1000 lub nawet do 1 000 000, bądź użyj liczb ujemnych (pamiętaj o niestosowaniu spacji ani kropek w liczbach całkowitych w języku Java). W ten sposób możesz udoskonalić nie tylko swoje umiejętności programistyczne, ale również matematyczne. Zachęcamy do zabawy z programem i modyfikowania go na różne sposoby!
STRATEGIA ODGADYWANIA
Z reguły im dłużej gramy w zgadywankę, tym mniejszej liczby prób potrzebujemy do odgadnięcia sekretnej liczby. W ten sposób możemy odkryć, że najszybsze rozwiązanie polega na wytypowaniu liczby znajdującej się w środku zakresu w każdej nowej próbie. Ta technika jest nazywana wyszukiwaniem binarnym. Typowanie liczby znajdującej się w środku potencjalnego zakresu za każdym razem skraca liczbę możliwości o połowę.
Metoda ta działa w następujący sposób. Z przedziału od 1 do 100 typujemy liczbę 50. Jeśli jest ona zbyt niska, wiemy, że sekretna liczba musi leżeć w przedziale od 51 do 100, a zatem typujemy środek przedziału, czyli 75. Jeśli ta liczba również jest zbyt niska, znowu typujemy liczbę w środku przedziału od 76 do 100, czyli 87. Wyszukiwanie binarne działa bardzo optymalnie i dla liczby z przedziału od 1 do 100 pozwala zredukować liczbę prób do maksymalnie siedmiu. Spróbuj sam(a)!
Po opanowaniu procesu zgadywania liczby od 1 do 100 w maksymalnie siedmiu próbach warto spróbować odgadnąć liczbę od 1 do 1000 w jedynie 10 próbach. A prawdziwi śmiałkowie (uzbrojeni w coś do pisania) mogą spróbować odgadnąć liczbę od 1 do 1 000 000. Choć trudno w to uwierzyć, powinno wystarczyć zaledwie 20 prób.
Zadanie 2: zliczanie prób
Zbudowaliśmy już całkiem fajną aplikację zgadywankę, jednak warto spróbować dodać jeszcze jedną funkcję. Zadanie polega na rejestrowaniu liczby prób i wyświetlaniu informacji, ilu prób użytkownik potrzebował do odgadnięcia sekretnej liczby. Rozwiązanie mogłoby wyglądać podobnie do następującego:
62 to prawidłowa liczba! Wygrywasz!
Liczba prób to jedynie: 7! Gratulacje!
Aby osiągnąć ten cel, trzeba utworzyć nową zmienną licznika prób (można dodać np. wiersz kodu int numberOfTries = 0;), a następnie zwiększać licznik prób podczas każdego wykonania pętli zgadywania. Możesz osiągnąć ten cel, zwiększając w każdym kolejnym wykonaniu pętli wartość zmiennej numberOfTries o jeden przy użyciu kodu numberOfTries = numberOfTries + 1. Pamiętaj o dodaniu tekstu informującego użytkownika o liczbie prób.
Nie zawsze od razu udaje się utworzyć kod, który realizuje odpowiednie operacje w odpowiedniej kolejności, jednak nie należy się zniechęcać, ponieważ poświęcony czas pomaga w utrwaleniu nowych umiejętności. W rozdziale 3 wbudujemy funkcję zliczania prób w inną wersję zgadywanki. A na razie mamy nadzieję, że przyjdą Ci do głowy dodatkowe pomysły na ulepszenie i zmodyfikowanie gry. Zabawa z programami, rozbieranie ich na części pierwsze i odbudowywanie to najlepszy sposób na naukę.
Zadanie 3: gra MadLibs
Ostatnie wyzwanie w tym rozdziale będzie polegało na napisaniu całkiem nowego programu. Wiesz już, jak odczytać dane wejściowe wpisane przez użytkownika i umieścić je w zmiennej. Umiesz także drukować tekst i wartości zmiennych na ekranie. Te umiejętności umożliwiają budowanie jeszcze ciekawszych programów.
Łączenie interfejsu GUI z kodem Javy
Czas połączyć układ GUI z kodem źródłowym Javy, aby rozpocząć programowanie działania aplikacji mobilnej Secret Messages. Otwieramy plik MainActivity.java, klikając zakładkę w lewym górnym rogu głównego okna zawartości. Bezpośrednio do deklaracji public class MainActivity dodajemy 5 następujących wierszy kodu:
public class MainActivity extends AppCompatActivity { EditText txtIn; EditText txtKey; EditText txtOut; SeekBar sb; Button btn;
Trzeba zaimportować klasy do kodu Java, naciskając alt-enter lub option-enter w poszczególnych wierszach kodu. Dodane zmienne wskazują komponenty GUI w wizualnym układzie aplikacji. Możemy połączyć nazwy zmiennych z prawdziwym widżetami, dodając pięć wierszy kodu do metody onCreate(), tuż pod instrukcją setSupportActionBar(toolbar):
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); txtIn = (EditText)findViewById(R.id.txtIn); txtKey = (EditText)findViewById(R.id.txtKey); txtOut = (EditText)findViewById(R.id.txtOut); sb = (SeekBar)findViewById(R.id.seekBar); btn = (Button)findViewById(R.id.button);
Funkcja Code Assist dostępna w Android Studio automatycznie uzupełni większość instrukcji – wystarczy wpisać kilka pierwszych znaków, a następnie wybrać pozycję z listy lub nacisnąć klawisz enter, aby zaakceptować podpowiadany kod. Takie podejście jest szybsze i pomaga unikać literówek.
Łączenie przycisku Encode z metodą encode()
Skoro mamy już kod połączony z komponentami układu GUI, możemy skopiować metodę encode() z komputerowej wersji aplikacji z rozdziału 7. Wkleimy metodę do deklaracji public class MainActivity, tuż pod dodanymi wcześniej pięcioma wierszami kodu deklarującymi zmienne, które wskazują komponenty GUI w układzie.
Otwieramy projekt komputerowy SecretMessagesGUI w programie Eclipse i zaznaczamy całą metodę encode(). Kopiujemy zaznaczony kod i wklejamy go w deklaracji public class MainActivity w Android Studio:
public class MainActivity extends AppCompatActivity { EditText txtIn; EditText txtKey; EditText txtOut; SeekBar sb; Button btn; public String encode( String message, int keyVal ) { String output = ""; char key = (char) keyVal; for ( int x = 0; x < message.length(); x++ ) { char input = message.charAt(x); if (input >= 'A' && input <= 'Z') { input += key; if (input > 'Z') input -= 26; if (input < 'A') input += 26; } else if (input >= 'a' && input <= 'z') { input += key; if (input > 'z') input -= 26; if (input < 'a') input += 26; } else if (input >= '0' && input <= '9') { input += (keyVal % 10); if (input > '9') input -= 10; if (input < '0') input += 10; } output += input; } return output; }
Po umieszczeniu metody encode() w kodzie aplikacji wystarczy wywoływać ją przy każdym kliknięciu przycisku Encode/Decode. W tym celu utworzymy metodę obsługi zdarzenia OnClickListener dla przycisku Encode/Decode i wywołamy w niej metodę encode(). W metodzie onCreate() w pliku MainActivity.java rozpoczynamy wpisywanie kodu btn.setOnCl aż do momentu pojawienia się podpowiedzi, jak pokazano na rysunku 8.9. Z listy wybieramy setOnClickListener().

Rysunek 9.4. Po dodaniu obsługi mousePressed() oraz ustawieniu BubbleListener w roli interfejsu słuchacza zdarzeń myszy w aplikacji możemy rysować bąbelki, klikając dowolne miejsce na ekranie
Odbieranie zdarzeń ruchu myszą
Zdarzenia ruchu myszą różnią się od zdarzeń naciśnięcia przycisku myszy, lecz mimo to mogą być przetwarzane w klasie rozszerzającej klasę MouseAdapter, takiej jak BubbleListener. Istnieją dwa typy zdarzeń ruchu myszą: mouseMoved() oraz mouseDragged().
Zdarzenie mouseMoved() następuje, gdy wskaźnik myszy przemieszcza się nad kanwą rysunku. Natomiast zdarzenie mouseDragged() następuje, gdy wskaźnik myszy przemieszcza się i jednocześnie naciśnięty jest przycisk myszy. Ponieważ chcemy rysować bąbelki tylko wtedy, gdy użytkownik klika i przeciąga wskaźnik myszy, zaprogramujemy najpierw obsługę zdarzenia mouseDragged() w klasie BubbleListener, a następnie dodamy do konstruktora BubblePanel interfejs słuchacza ruchu, aby aktywować działanie słuchacza. Dodajemy metodę obsługi zdarzeń mouseDragged() do klasy BubbleListener, jak pokazano poniżej:
private class BubbleListener extends MouseAdapter { public void mousePressed(MouseEvent e) { --wycinek } public void mouseDragged(MouseEvent e) { bubbleList.add(new Bubble(e.getX(), e.getY(), size)); repaint(); } }
Jak widać, kod wygląda niemal tak samo jak kod metody obsługi zdarzenia mousePressed(), różni się jedynie nazwą mouseDragged(). Wynika to z faktu, iż obie metody obsługują zdarzenia MouseEvent. Metoda mousePressed() obsługuje zdarzenia, gdy użytkownik naciśnie przycisk myszy, natomiast metoda mouseDragged() jest wywoływana, gdy użytkownik przeciągnie wskaźnik myszy. W tej aplikacji oba zdarzenia powinny dawać ten sam rezultat – dodanie bąbelka bubbleList i wywołanie funkcji repaint().
A teraz dodajemy BubbleListener jako słuchacza zdarzeń ruchu myszy do konstruktora BubblePanel(), używając następującej instrukcji:
public BubblePanel() { bubbleList = new ArrayList<Bubble>(); setBackground(Color.BLACK); // testBubbles();
addMouseListener( new BubbleListener() ); addMouseMotionListener( new BubbleListener() ); }
Ponownie uruchamiamy aplikację w celu przetestowania tego nowego słuchacza zdarzeń. Zapisujemy kod, naciskamy przycisk uruchamiania i klikamy oraz przeciągamy wskaźnik myszy w wyświetlonym oknie aplikacji, jak pokazano na rysunku 9.5.

Rysunek 9.5. Teraz możemy rysować ciągłe strumienie bąbelków, przeciągając wskaźnik myszy
Imponujące, prawda? W języku Java wystarczy dodać do BubblePanel dwie metody obsługi zdarzeń przycisku oraz ruchu wskaźnika myszy, aby uzyskać interaktywną, kolorową aplikację rysującą.