Stand: 21.07.2018
Wir programmieren eine erste App und lernen Grundbegriffe kennen, die wir später ausbauen.
Die einfachste mögliche App besteht aus einer Activity und einem View. In der View definieren wir die grafische Oberfläche (die Screen), d.h. welche Komponenten (Buttons, Texte etc.) sichtbar sind. In der Activity, die aus Java-Code besteht, legen wir die Funktionalität fest, also z.B. welche Aktionen ausgeführt werden, wenn man auf einen Button drückt.
Zunächst legen wir ein erstes Projekt an und erläutern anhand dessen die Konzepte Activity und View. Am Ende soll unser erstes Projekt wie folgt aussehen:
2.1 Projekt anlegen
Mit File > New > New Project... legen wir ein neues Projekt an.
Dazu geben Sie einen Namen, den Ablageort (Verzeichnis, i.d.R. gleicher Name wie das Projekt) und die "Domäne" an. Die Domäne wird dann rückwärts gelesen als Paketname benutzt, also z.B. wird aus Domäne hsa.de das Paket de.hsa:
Anschließend legen Sie die Minimalvoraussetzungen für Ihr Projekt fest. Android liegt ja in vielen Versionen vor. Je höher sind gehen, umso mehr Features können Sie nutzen, dafür können aber Android-Geräte mit älteren Versionen Ihre App nicht abspielen.
Geben Sie dann Empty Activity an. Bei den anderen Optionen wird zusätzlicher Code erzeugt, der zu Beginn verwirrend sein kann:
Hier lassen Sie einfach die Defaultwerte drin:
2.1.1 Projektansicht
Jetzt öffnet sich die "normale" Projektansicht mit einem großen Code-Bereich rechts, der natürlich noch leer ist.
Falls Sie links kein Teilfenster haben, klicken Sie auf project am linken Rand des Gesamtfensters.
Im linken Teilfenster sehen Sie Ihr Projekt und die entsprechenden Verzeichnisse, hier haben wir einige ausgeklappt:
Die Projektsicht ist eine vereinfachte Sicht auf Ihre Verzeichnisse. Android Studio will Ihnen so das navigieren erleichtern. Im nächsten Abschnitt sehen wir, wie das auf der Festplatte aussieht.
2.1.2 Auf der Festplatte
Wo befinden sich die Verzeichnisse auf der Festplatte? Wenn Sie in Ihr Projektverzeichnis gehen, sehen Sie:
Sie sehen also, dass die Projektsicht in Android Studio vereinfacht ist. Auf der Festplatte müssen Sie zuerst in app/src/main hineingehen.
Sinnvoll ist noch ein Blick in das Verzeichnis app/src/main/res:
Hier liegen die sogenannten Ressourcen (engl. resources), dazu gehören u.a. auch Bilder und Videos, die Sie hier deponieren - Bilder z.B. unter drawable.
2.2 Activity: Der Einstiegspunkt
Eine Android-App ist im Grunde eine Ansammlung von Activities. Man kann sich eine Activity als eine Bildschirmseite auf dem Smartphone vorstellen. Clickt oder wischt man zu einer anderen Seite, befindet man sich in der nächsten Activity.
Öffnen Sie jetzt den Code von MainActivity
im Verzeichnis java
(und dem von Ihnen fest gelegten Paket). Sie sehen jetzt Java-Code und insbesondere die Methode onCreate(). Das ist Ihr Einstiegspunkt!
package de.hsa.myapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// DIESE ZWEI ZEILEN NICHT ÄNDERN!
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// AB HIER EIGENER CODE
}
}
Wie Sie sehen, ist eine Activity eine Java-Klasse, genauer gesagt eine Unterklasse der vorgegebenen Android-Klasse Activity
bzw. AppCompatActivity
(steht für app compatibility). Diese Activity ist der Einstiegspunkt in die App. Im Gegensatz zu einem traditionellem Java-Programm gibt es keine statische Methode main()
. Stattdessen wird beim Start der App die Methode onCreate()
in MainActivity aufgerufen.
Eigenen Code fügen Sie i.d.R. innerhalb von onCreate
ein, aber unterhalb der ersten zwei Zeilen.
Schauen Sie gern auch mal in die API der Klasse AppCompatActivity
. Sie sehen dort, dass die Klasse auch von der abstrakten Klasse Context
abstammt (siehe API). Dieser Klasse werden wir noch öfter begegnen, wenn es darum geht, die Activity einer Methode "mitzugeben".
Die Activity, die zu Beginn einer App gestartet wird, nennt man auch Root Activity. Erstaunlich viele Apps bestehen nur aus dieser einen Activity, da es üblich ist, auf mobilen Geräten viele "kleine" Applikationen zu haben, die eine spezifische Aufgabe übernehmen. Zu jeder Activity gehört eine entsprechende grafische Oberfläche, die man als View bezeichnet.
Hat man mehrere Activities innerhalb der App, bedient man sich den Intents, um von einer Activity in die nächste zu kommen (siehe Modul Intents). Wir gehen aber im weiteren von einer App mit einer einzigen Activity aus.
2.3 View: Grafische Oberfläche
Die grafische Oberfläche besteht aus Komponenten, die man in einem Layout anordnet. Die View wird in Form eines XML-Dokuments (z.B. activity_main.xml
) spezifiziert, das im Verzeichnis res/layout
vorliegt:
In Android Studio sehen Sie zunächst die Design-Ansicht der Datei. Diese Ansicht erlaubt ein grafisches Editieren des Layouts:
Links unten sehen Sie zwei Reiter (Tabs) namens Design und Text. Wenn Sie auf "Text" klicken, sehen Sie die Text-Ansicht der XML-Datei. Die Ansicht auf die Datei ist häufig notwendig, um Details zu prüfen und um die Funktionsweise des Layouts besser zu verstehen.
2.3.1 Exkurs: XML
XML ist eine Möglichkeit, strukturierte Daten darzustellen. Ein XML-Dokument besteht aus Elementen, wobei jedes Element einen öffnenden und einen schließenden Tag (wird englisch ausgesprochen, also /täg/) hat. Zum Beispiel könnte es ein foo-Element geben:
<foo>
Hier kann irgendwas stehen.
</foo>
Ein Element kann andere Elemente enthalten:
<foo>
Hier kann irgendwas stehen.
<bar>
</bar>
<doo>
</doo>
</foo>
Ein Element kann Attribute haben, die immer im öffnenden Tag stehen:
<foo size="150" color="blue" url="http://something.com">
Hier kann irgendwas stehen.
</foo>
Manchmal ist es nicht nötig einen öffnenden und einen schließenden Tag zu haben. Das Element besteht quasi nur aus einem Tag. Dann signalisiert man das mit einem Slash am Ende:
<foo size="150" />
Man nennt einen solchen Tag auch einen Leer-Tag.
Eine ausführliche Beschreibung von XML finden Sie in Kapitel 1 meines Skripts zu Webtechnologien.
2.3.2 Text-Ansicht
Kehren wir zurück zu unserer Text-Ansicht des Layouts. Die Datei, die per Default erzeugt wird, sieht wie folgt aus. Die hat zwei Elemente (ConstraintLayout und TextView), wobei TextView in ConstraintLayout enthalten ist.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="de.hsa.myapp.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Löschen Sie das vorhandene TextView-Element, indem Sie
- in der Design-Ansicht das Element anklicken und auf die Löschtaste drücken oder
- in der Text-Ansicht den TextView-Block, also alles von "
", löschen.
Anschließend ziehen Sie in der Design-Ansicht einen Button aus der Palette (Leiste links neben dem grafischen Fenster) und positionieren ihn in die Mitte. In der rechten Leiste können Sie den Text des Buttons ändern zu "Hallo". Sie können auch die Textgröße im Feld "textSize" ändern, z.B. auf "30sp".
Wenn Sie in der Text-Sicht sind, können Sie zusätzlich den Preview aktivieren (Button ist ganz rechts im Rand des Gesamtfensters), so dass Sie sowohl XML als auch GUI im Blick haben. So können Sie auch beobachten, welche Änderungen sich ergeben, wenn Sie im XML editieren.
2.4 Testen: Emulator verwenden
Wenn Sie Ihr Projekt starten, können Sie
- die App auf einem echten Android-Smartphone oder -Tablet ausführen oder
- die App auf einem simulierten Gerät auf dem Rechner starten
Wir schauen uns Option zwei an und starten die App auf einem sogenannten Emulator. Dazu müssen Sie für den Emulator die Geräte installieren (unterschiedlichste Smartphone- und Tablet-Modelle).
Wollen Sie Ihre App auf einem echten Endgerät starten, müssen Sie das Gerät in den Entwicklungsmodus versetzen und das USB-Debugging aktivieren (dazu gibt es viele Anleitungen im Netz). Dann schließen Sie das Gerät per USB-Kabel an den Rechner an. Android Studio wird dann Ihr Smartphone/Tablet beim Start mit Run als Option anbieten.
Wir sehen hier, dass unser Button nach links oben gerutscht ist. Das heißt, wir müssen uns mit dem komplexen Thema Layout auseinander setzen, das verschärft wird durch die vielen unterschiedlichen Screen-Größen und durch den Unterschied der Portrait/Landscape-Orientierungen. Dazu in einem eigenen Kapitel mehr.
2.5 Interaktion: Auf Buttons reagieren
Wir möchten jetzt mit der App interagieren, d.h. dass eine Aktion des Users eine Reaktion in der App hervorruft. Als kleines Beispiel möchten wir, dass beim Druck auf den Button der Text des Buttons sich ändert zu "Welt".
Schauen wir uns in "activity_main" die Textansicht an. Wir sehen den Button in diesem Schnipsel:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hallo"
android:textSize="30sp"
tools:layout_editor_absoluteX="133dp"
tools:layout_editor_absoluteY="225dp" />
Wichtig ist der ID des Buttons.
android:id="@+id/button"
Diesen benötigen wir, wenn wir im Code von MainActivity.java darauf zugreifen wollen. Aber wie können wir vom Java-Code aus auf eine Komponente zugreifen, die in irgendeinem XML-File definiert ist? Die Antwort ist die Klasse R, die Android automatisch erzeugt und die über statische Variablen den Zugriff auf die IDs der Komponenten erlaubt.
In der Methode onCreate
protected void onCreate(Bundle savedInstanceState) {
...
}
verwenden wir die Methode findViewById
, um die richtige Komponente herauszufischen. Bei gibt uns der Ausdruck "R.id.button" den ID des Buttons zurück.
Button halloButton = (Button)findViewById(R.id.button);
UPDATE: Seit API 26 benötigt die Methode findViewById
kein Casting mehr. Dann wird daraus:
Button halloButton = findViewById(R.id.button);
Anschließend hängen wir ein Stück Code zur Ausführung an dieses Button-Objekt. Wir verwenden dazu eine sogenannte "anonyme innere Klasse", über die wir später noch reden werden:
halloButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
halloButton.setText("Welt");
}
});
Aufgrund der Position des Code-Schnipsels "halloButton.setText("Welt")" innerhalb einer inneren Klasse, müssen wir die Variable halloButton "final" machen. Der komplette Code ist:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button halloButton = findViewById(R.id.button);
halloButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
halloButton.setText("Welt");
}
});
}
Wenn Sie jetzt die App starten und auf den Button klicken, sehen Sie, dass der Text zu "Welt" verändert wird. Ihr erste Interaktion!
2.6 Zusammenfassung
Jede App besteht aus einer Reihe von Activities. Man kann sich zunächst mal jede Activity als eine Screen einer App vorstellen. Jede Activity hat eine View, das sind alle grafischen Komponenten (Buttons, Texte, Bilder) und das dazugehörige Layout.
Im einfachsten Fall nehmen wir die eine vorgegebene Activity MainActivity.java
. Sie ist unser Einstiegspunkt, hier wird in Java die Funktionalität der App programmiert. Das Layout definieren wir in der zur Activity gehörigen XML-Datei activity_main.xml
. Dazu gibt es auch einen grafischen Editor, der uns dabei unterstützt (Design-Ansicht).
Wir testen unsere Apps in der Regel mit einem Emulator. Das ist ein Programm, das ein Smartphone oder ein Tablet auf unserem Computer simuliert. Wir können aber auch auf echten Endgeräten testen, die wir per USB-Kabel anschließen und die vorab in den Entwicklungsmodus geschaltet wurden.
Interaktion bedeutet, dass unsere App auf eine Aktion des Users reagiert, z.B. auf das Berühren eines Buttons. Dazu beziehen wir das Java-Objekt des Buttons mit Hilfe der Methode findViewById
und der Klasse R, welche die IDs aller Komponenten enthält. Anschließend "hängen" wir einen sogenannten Listener an das Button-Objekt mit Hilfe der Methode setOnClickListener
. In dem Listener-Code können wir z.B. grafische Komponente verändern, etwa einen neuen Text in eine Textkomponente schreiben.
2.7 Übungen
(A) Hallo-Button
Erzeugen Sie ein Projekt, wo Sie alle Schritte dieses Kapitels einbauen und testen, d.h. Sie haben eine erste App mit einem Hallo-Button. Der Button ändern beim Anklicken seine Schrift zu "Welt".
(B) Zweiter Button
Fügen Sie einen zweiten Button hinzu.
Ändern Sie die Beschriftung des Buttons zu "OK".
Ändern Sie den ID des Buttons zu "okButton".
Lassen Sie folgenden Code ausführen, wenn der Button gedrückt wird:
Toast.makeText(view.getContext(), "OK gedrückt", Toast.LENGTH_SHORT).show();
Starten Sie Ihre App und schauen Sie, was passiert, wenn Sie auf den Button drücken.
(C) Textfeld
Fügen Sie ein Textfeld hinzu (TextView), z.B. mit dem Text "Meine erste App", und platzieren Sie das Textfeld über dem Button. Was passiert, wenn Sie die App im Emulator laufen lassen?