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).

Następna część - Wstęp