Obsługa zdarzeń i logika aplikacji (Activity)¶
Żeby obsłużyć zdarzenie polegające na naciśnięciu przycisku, musimy do opisu xml elementu Layout dodać odpowiedni znacznik wskazujący która funkacja ma zostać wywołana w celu obsłużenia zdarzenia polegającego na naciśnięciu tego przycisku. W naszym przypadku, do opisu przycisku b1 dodajemy atrybut android:onClick, któremu nadajemy wartość b1_pressed, która wskazuje że w celu obsłużenia zdarzenia należy wywołać funkcję składową b1_pressed klasy opisującej Activity powiązaną z tym obiektem Layout.
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/b1_text"
android:id="@+id/b1"
android:layout_marginTop="49dp"
android:layout_alignParentTop="true"
android:onClick="b1_pressed"/>
Definicję Klasy opisującej Activity znajdziemy w pliku /app/src/main/java/com/delta/tango mod2. W chwili tworzenia obiektu Layout, automatycznie wywoływana jest metoda protected void onCreate(Bundle savedInstanceState) skojarzonego z nim obiektu Activity. Do metody tej jest automatycznie przekazywany obiekt klasy Bundle, zawierający informację o zapisanym stanie obiektu.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Łącznikiem pomiędzy opisem interfejsu (xml) a działaniami aplikacji (Java) jest automatycznie generowana przez Android SDK klasa R, którą można znaleźć w pliku /app/build/generated/source/r/debug/com/delta/tango/mod2/R.java. Klasa ta definiuje szereg pól statycznych, które zawierają referencje do odpowiadających im elementów interfejsu graficznego (Layout).
public final class R
{
...
public static final class layout
{
...
public static final int activity_main=0x7f040019;
...
}
...
}
Utworzona przez kreator metoda onCreate() składa się z wywołania metody onCreate() z nadklasy i przekazaniu do niej otrzymanego jako parametr obiektu savedInstanceState
super.onCreate(savedInstanceState)
oraz z wywołania metody
setContentView(R.layout.activity_main)
ustawiającej Layout opisany w formie xml w activity_main.xml. Przeanalizuj definicję klasy R i narysuj na kartce jej strukturę. Zastanów się jakiego typu elementy składowe posiada i jakie elementy interfejsu graficznego reprezentuje.
Komponenty naszego interfejsu graficznego możemy teraz obsłużyć na przykład za pomocą metody findViewById(), która przyjmuje jako parametr identyfikator komponentu i zwraca reprezentujący go obiekt android.view.View. W tym celu w activity_main.xml usuń atrybut android:text w opisie pola tekstowego tv1 (pole tekstowe po uruchomieniu nie będzie posiadać żadnego tekstu). Następnie w klasie MainActivity zaimplementujmy metodę b1_pressed
public void b1_pressed(android.view.View v)
{
android.widget.TextView obj=(android.widget.TextView)findViewById(R.id.tv1);
obj.setText("Greatest failure is not to try");
}
Pełne nazwy klas (android.view.View i android.widget.Widget), złożone z nazwy pakietu i nazwy klasy, możemy oczywiście zastąpić krótkimi nazwami klas. W tym celu, w pliku Main Activity.java, po deklaracji pakietu a przed definicjami klas musimy dodać odpowiednie dyrektywy import (zob. poprzedni moduł). Przetestuj aplikację.
Ćwiczenie 1¶
Wykorzystując wiadomości dotyczące programowania w języku Java, rozwiń aplikację w ten sposób żeby po każdym naciśnięciu przycisku „Aforyzm dnia” wypisywała na ekranie aforyzm losowo wybrany spośród tekstów przechowywanych w pliku strings.xml (w odpowiedniej wersji językowej)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">cw1</string>
<string name="menu_settings">Settings</string>
<string name="b1text">Aforyzm dnia</string>
<string name="tv1text">Greatest failure is not to try</string>
<string name="eracism">The greatest failure is not to try</string>
<string name="latin">To err is human, but being right is nice too</string>
<string name="latin2">Lex retro not agit</string>
</resources>
Będziesz musiał także zdefiniować w formacie xml odpowiednią tablicę tekstów. W tym celu dodaj plik res/values/arrays.xml i dodaj do niego definicję
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name="tab_aforyzmy">
<item>@string/eracism</item>
<item>@string/latin</item>
<item>@string/latin2</item>
</string-array>
</resources>
Losowy wybór tekstu do wypisania na ekranie musisz zaimplementować w języku Java, wykorzystaj do tego klasę Random z pakietu java.Util (generator liczb pseudolosowych).
java.util.Random gen=new java.util.Random();
int i=gen.nextInt(tab.length);
String[] tab=getResources().getStringArray(R.array.tab_aforyzmy);
TextView obj=(TextView)findViewById(R.id.tv1);
obj.setText(tab[i]);
Potrzebne informacje znajdziesz w module dotyczącym podstaw programowania w języku Java.
Ćwiczenie 2¶
Dodaj do aplikacji kolejny komponent interfejsu graficznego, na przykład Spinner, i za jego pomocą rozwiń aplikację poprzez wybór kategorii aforyzmów spośród których mają być losowany aforyzm dnia (na przykład według autorów lub krajów pochodzenia).
Ćwiczenie 3¶
W oparciu o wiadomości z tego modułu oraz z modułu dotyczącego programowania w języku Java napisz implementacje kalkulatora dla platformy Android. Twój kalkulator powinien posiadać przyciski z cyframi oraz odpowiednimi działaniami. W tym celu będziesz potrzebował konwersji Będziesz potrzebował konwersji informacji tekstowych z obiektu klasy CharSequence to obiektu klasy String oraz parsowania tekstu do zmiennopozycyjnego typu danych (na przykład double) oraz z typu liczbowego to tekstowego (w drugą stronę).
TextView obj=(TextView)findViewById(R.id.tv1);
CharSequence cs=obj.getText();
String s=cs.toString();
double x=Double.parseDouble(s);
x=x*x;
String s2=Double.toString(x);
tv.setText(s2);
Zaimplementuj podstawowe działania arytmetyczne, potęgowanie, pierwiastkowanie, procenty, silnię, logarytmy, funkcje trygonometryczne, pamięć (lub grupowanie działań za pomocą nawiasów).