In dieser Lektion werden wir eine XML-Layout Datei erstellen und mit ihrer Hilfe das Aussehen unserer Start-Activity anpassen.
Dabei werden wir die visuelle Struktur der Android Benutzeroberfläche näher kennenlernen und erfahren, welche Vorteile sich durch das Verwenden von Layout Dateien ergeben.
Die erstellte XML-Layout Datei muss in einem ganz bestimmten Ressourcen-Ordner, dem layout-Ordner, unseres Android Projekts abgelegt werden. Da der Ordner noch nicht existiert, werden wir ihn vorher von Android Studio anlegen lassen.
Am Ende dieser Lektion werden wir von der Klassendatei der Start-Activity aus auf die erstellte Layout Datei zugreifen. Dazu werden wir die Datei MainActivity.java
im Editor öffnen und Anpassungen an ihrem Quellcode vornehmen. Zum Testen der vorgenommenen Änderungen werden wir unsere App anschließend im Emulator ausführen.
1. Die Benutzeroberfläche von Android Anwendungen
In Android wird das Layout der Benutzeroberfläche mit Hilfe von ViewGroup– und View-Objekten definiert. Ein ViewGroup-Objekt ist ein unsichtbarer Container, der mehrere View– und auch ViewGroup-Objekte in sich aufnehmen und verwalten kann. Ein View-Objekt ist ein sichtbares Bildschirmelement, mit dem der Benutzer interagieren kann.
Da keine anderen Objekte für das Definieren von Layouts verwendet werden, besteht in Android jede Benutzeroberfläche aus einer Hierarchie von ViewGroup– und View-Objekten. Diese Objekte bilden im Verbund eine Baumstruktur beliebiger Komplexität, wie in der unteren Abbildung beispielhaft dargestellt.
Beispiel einer Hierarchie von View- und ViewGroup-Objekten, die zusammen das Layout der Benutzeroberfläche definieren
Hinweis: Aus Performance-Gründen sollte immer eine möglichst flache Hierarchie angestrebt werden. Layouts mit einer flachen Hierarchie werden schneller gezeichnet als verschachtelte Layouts mit tiefer Hierarchie.
Um ein solches Layout auf dem Bildschirm des Android Geräts darstellen zu lassen, sind zwei Schritte notwendig. Zunächst muss das Layout durch Anordnen verschiedener View– und ViewGroup-Objekte definiert werden. Anschließend wird das Layout in einer Activity mit Hilfe der setContentView() Methode geladen. Wir werden nun beide Arbeitsschritte ausführlich betrachten.
1.1 Definieren eines Layouts in Android
Wie bereits erwähnt, werden in Android XML-Layouts für das Definieren der visuellen Struktur der grafischen Benutzeroberfläche verwendet. Ein solches Layout kann auf zwei Arten definiert werden:
-
Vorgeben der UI-Elemente in XML – Die Elemente der Benutzeroberfläche (UI-Elemente) können in einer XML-Layout Datei in Form einer Baumstruktur vorgegeben werden. Das zur Verfügung stehende XML-Vokabular entspricht dabei direkt den View– und ViewGroup-Klassen von Android.
-
Instanziieren der UI-Elemente zur Laufzeit – In Android Anwendungen können View– und ViewGroup-Objekte Code-gesteuert (programmatisch) erzeugt und ihre Eigenschaften verändert werden. Auf diese Weise können Layout-Objekte zur Laufzeit erstellt und zu einer Baumstruktur miteinander verbunden werden.
Das Android Framework ist so flexibel, dass sogar beide Methoden zusammen für das Erstellen und Verwalten der UI-Elemente (User Interface Elemente) verwendet werden können. Bspw. können über eine XML-Layout Datei das Standardlayout der App definiert und dessen UI-Elemente später zur Laufzeit per Code manipuliert werden.
In der MainActivity.java
Klassendatei haben wir bereits ein View-Objekt, nämlich das TextView-Objekt, per Quellcode angelegt. Das TextView-Objekt haben wir in der onCreate() Methode der Activity instanziiert und anschließend als Bildschirminhalt mit Hilfe der setContentView() Methode festgelegt.
Besser ist es jedoch das Layout in einer XML-Layout Datei zu definieren und dieses Layout dann in der jeweiligen Activity mittels der setContentView() Methode zu laden.
Dieses Vorgehen, also das Verwenden von XML-Layout Dateien, bietet zwei große Vorteile:
-
Trennung von Layout und Code – Die visuelle Struktur der Anwendung wird durch XML-Layout Datei von dem Quellcode, der das Verhalten der App steuert, getrennt. Die Definition der Benutzeroberfläche ist extern ausgelagert und kann überarbeitet werden, ohne das dafür der Quellcode verändert und erneut kompiliert werden muss.
Zum Beispiel können XML-Layout Dateien für verschiedene Bildschirmorientierungen, Bildschirmgrößen und Sprachen angelegt werden. Zur Laufzeit kann dann entschieden werden, welches Layout auf dem jeweiligen Android Gerät verwendet werden soll.
-
Visualisieren der UI-Struktur – Durch Definieren des Layouts per XML-Dateien kann die visuelle Struktur der Benutzeroberfläche einfacher dargestellt werden. Dadurch können Darstellungsprobleme leichter erkannt und behoben werden. Zudem kann der Layout Editor von Android Studio für das Visualisieren und Verwalten der Layouts genutzt werden. Die UI-Elemente können dabei komfortabel per Drag & Drop angeordnet werden.
Im Allgemeinen entspricht das XML-Vokabular für das Vorgeben der UI-Elemente den tatsächlichen View– und ViewGroup-Klassen und -Methoden. Wobei der Elementname dem Klassennamen und der Attributname dem Methodennamen entspricht. So korrespondiert das <TextView> Element im XML-Layout mit der TextView-Klasse des Android Framework.
Hinweis: Es gibt jedoch auch leichte Namensunterschiede. Bspw. besitzt das <TextView> Element das text-Attribut, welches der TextView.setText() Methode entspricht.
Mit folgendem XML-Code wird ein einfaches vertikales Layout definiert:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:id="@+id/textview_activity_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello CodeYourApp World! per XML-Layout" /> <Button android:id="@+id/button_activity_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Push Me" /> </LinearLayout>
Das oben definierte Layout besitzt als Wurzelelement ein ViewGroup-Objekt, das durch ein <LinearLayout> Element definiert wird. In dem ViewGroup-Objekt befinden sich zwei View-Objekte, welche durch ein <TextView> und ein <Button> Element definiert werden. Über die verschiedenen Attribute werden die Eigenschaften der Elemente vorgegeben.
Durch einfaches Nutzen des Android XML-Vokabulars kann auf diese Weise sehr effektiv ein gut strukturiertes UI-Layout erstellt werden. Dabei ist unbedingt zu beachten, das jedes XML-Layout genau ein Wurzelelement besitzt muss. Dieses kann entweder ein View– oder ViewGroup-Objekt sein.
Nachdem das Layout der Benutzeroberfläche in XML definiert wurde, muss es in einer sogenannten Layout Datei mit der Endung .xml
abgespeichert werden. Diese XML-Datei muss in dem res/layout/ Ordner des Android Studio Projekts abgelegt werden, damit sie ordnungsgemäß kompiliert wird. Bei leeren Projekten muss dieser Ordern noch per Hand erstellt werden.
Wird auf die eben beschriebene Art ein UI-Layout in XML definiert, kann es in der App sehr einfach als Benutzeroberfläche für die Activity genutzt werden. Wie dies erfolgt, beschreiben wir im nächsten Abschnitt.
1.2 Laden eines Layouts in Android
Wie bereits zu Beginn dieser Lektion erwähnt, sind zwei Schritte notwendig, um ein Layout auf dem Bildschirm des Android Geräts darstellen zu lassen. Den ersten Schritt (Definieren eines UI-Layouts) haben wir im vorherigen Abschnitt ausgiebig besprochen. Nun möchten wir uns dem zweiten Arbeitsschritt zuwenden und zeigen, wie ein bereits definiertes UI-Layout aus einer XML-Ressource geladen wird.
Beim Kompilieren der eigenen App in Android Studio, wird jede XML-Layout Datei des res/layout/ Ordners in eine View-Ressource umgewandelt. Diese Layout-Ressourcen können in der onCreate() Methode der Activity-Klasse durch Aufrufen der setContentView() Methode geladen werden. Als Argument muss der setContentView() Methode die Referenz zur Layout-Ressource übergeben werden. Dies geschieht in der Form: R.layout.layout_filename
.
Hinweis: Die onCreate() Methode der Activity-Klasse wird automatisch vom Android Framework aufgerufen, sobald die Activity gestartet wird. Aus diesem Grund muss das Laden des UI-Layouts in dieser Methode stattfinden.
Ist das UI-Layout bspw. in einer XML-Datei mit dem Dateinamen activity_main.xml
abgespeichert worden, würde eine einfache Implementation der onCreate() Methode dann wie folgt aussehen:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
In Zeile 3 wir das UI-Layout geladen und als Bildschirminhalt festgelegt. Dabei wird auf die lokale Ressourcen-Klasse R.java
zugegriffen, in der alle für das Android Projekt relevanten Ressourcen verwaltet werden.
Die R Klasse wird beim Kompilieren des Projekts automatisch von dem aapt-Tool (android asset packaging tool) generiert. Sie enthält Ressourcen-IDs für alle Ressourcen innerhalb des res/ Ordners. Für jeden Ressourcen-Typ besitzt sie eine Unterklasse (bswp. R.layout für alle Layout-Ressourcen) und für jede Ressource dieses Typs besitzt sie eine Integer-Konstante (bspw. R.layout.activity_main für die XML-Layout Datei activity_main.xml
). Dieser Integer-Wert ist die Ressourcen-ID, mit deren Hilfe auf die Ressource zugegriffen werden kann.
2. Erstellen der XML-Layout Datei
Wie man die visuelle Struktur einer Android App in XML definiert und in einer Activity verwendet, haben wir nun ausführlich kennen gelernt.
Nun ist es an der Zeit die Theorie in die Praxis umzusetzen. Dazu werden wir für unsere Android App eine XML-Layout Datei erstellen und in ihr ein einfaches UI-Layout definieren. Dieses Layout werden wir anschließend unserer Start-Activity als Benutzeroberfläche zuweisen.
Die zu erstellende XML-Layout Datei muss in dem res/layout/ Ressourcen-Ordner abgelegt werden. Dieses Verzeichnis existiert momentan noch nicht in unserem Android Projekt und muss daher von uns erstellt werden.
Somit besteht das Anlegen des XML-Layouts für die Start-Activity aus den folgenden beiden Arbeitsschritten:
-
Anlegen des layout-Ordners – Wir legen in dem Ressourcen-Ordner unseres Android Studio Projekts den layout-Ordner an. In ihm werden alle zukünftigen XML-Layout Dateien für Activities und Fragmente abgelegt.
-
Erstellen der XML-Layout Datei – In dem erstellten layout-Ordner lassen wir von Android Studio eine neue XML-Layout Datei mit dem Dateinamen
activity_main.xml
erstellen. Anschließend definieren wir in der erstellten Layout Datei die grafische Benutzeroberfläche unserer Start-Activity per Android XML-Vokabular.
Beginnen wir nun mit dem ersten Arbeitsschritt.
2.1 Anlegen des layout-Ordners in Android Studio
Alle XML-Layout Dateien müssen in dem layout-Ordner des Android Projekts abgelegt werden. Nur Layout Dateien die sich im res/layout/ Ordner befinden, werden beim Kompilieren der App in eine View-Ressource umgewandelt. Zudem wird beim Kompilieren auch die lokale Ressourcen-Klasse R generiert, welche die Ressourcen-IDs für alle Ressourcen innerhalb des gesamten res/ Verzeichnisses enthält.
Wir werden nun den layout-Ordner anlegen. Dazu gehen wir folgendermaßen vor:
- Mit der rechten Maustaste auf den Ordner res/ in dem Project Tool Window klicken.
- Anschließend den Eintrag New des Kontext-Menüs anklicken.
- Danach auf Directory klicken.
Anschließend öffnet sich der New Directory-Dialog, in welchem wir den Namen des zu erstellenden Ordner vorgeben müssen:
Hinweis: Sollte sich der New Directory-Dialog bei euch nicht automatisch öffnen, liegt das an einem Bug in Android Studio. Dieser Bug wird hoffentlich bald behoben. Bis es soweit ist, muss das neue Verzeichnis, wie in der folgenden Animation dargestellt, angelegt werden:
Sollte bei euch der Bug nicht auftreten und der New Directory-Dialog automatisch erscheinen, kann das Verzeichnis wie gewohnt erstellt werden. Beide Wege führen zu dem selben Ergebnis.
Wir tragen in das Feld Enter new directory name den Wert layout ein und bestätigen anschließend den Dialog mit einem Klick auf den OK Button.
Nun legt Android Studio den Ressourcen-Ordner layout/ für unsere XML-Layout Dateien automatisch an.
2.2 Erstellen der XML-Layout Datei activity_main.xml
Als nächsten Schritt erstellen wir die XML-Layout Datei activity_main.xml
, mit welcher wir das Aussehen unserer Start-Activity definieren. Dazu führen wir die folgenden Schritte aus:
- Zunächst den res/ Ordner in dem Project Tool Window mit einem Doppelklick aufklappen.
- Danach mit der rechten Maustaste auf den eben erstellten layout/ Ordner klicken.
- Anschließend den Eintrag New des Kontext-Menüs anklicken.
- Und schließlich auf Layout resource file klicken.
Anschließend öffnet sich der New Layout Resource File-Dialog, der uns bei der Erstellung der XML-Ressourcen Datei unterstützt. Wir müssen nur die beiden Felder des Dialogs ausfüllen.
In dem New Layout Resource File-Dialog nehmen wir nun die folgenden Einstellungen vor:
- Als Dateinamen tragen wir in das Feld File name activity_main.xml ein.
- Den Wert für das Root element (Wurzelelement des UI-Layouts) lassen wir auf LinearLayout stehen.
Anschließend bestätigen wir den New Layout Resource File-Dialog mit einem Klick auf den OK Button, woraufhin die neue XML-Ressourcen Datei automatisch von Android Studio erstellt und im Editorfenster der IDE geöffnet wird.
Falls die Datei nicht automatisch geöffnet wurde, führen wir das Öffnen manuell durch. Dazu klicken wir doppelt auf ihren Dateinamen activity_main.xml
im Project Tool Window von Android Studio. Die Datei befindet sich im res/layout/ Ordner unseres Projekts.
Standardmäßig öffnet sich das Editorfenster in der Design-Ansicht. Damit der XML-Code der Layout Datei angezeigt wird, müssen wir im Editorfenster den Tab Code anklicken.
Den generierten XML-Code löschen wir vollständig und fügen an dessen Stelle den folgenden XML-Code ein:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:layout_margin="20dp"> <TextView android:id="@+id/textview_activity_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:textSize="18sp" android:text="Hello CodeYourApp World! per XML-Layout" /> <Button android:id="@+id/button_activity_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:text="Push Me" /> </LinearLayout>
Mit dem oberen Quellcode definieren wir das UI-Layout für unser Start-Activity. Die visuelle Struktur der Activity besteht aus einem LinearLayout-, TextView– und Button-Element. Das LinearLayout-Element ist das Wurzelelement des XML-Layouts und nimmt in sich die beiden anderen UI-Elemente auf.
Für die beiden View-Objekte, das TextView– und Button-Element, haben wir jeweils eine ID anlegen lassen. Dazu verwenden wir die folgende Schreibweise: android:id=“@+id/element_name“.
Über die ID kann später auf das View-Objekt zugegriffen werden. Durch das @ Symbol weiß der XML-Parser, dass es sich um eine ID-Ressource handelt. Das + Symbol gibt an, dass die ID-Ressource in der R.java
Datei neu angelegt werden muss.
In Android Studio sollte die activity_main.xml
Datei nun wie folgt aussehen:
Nun haben wir das UI-Layout für unsere Start-Activity angelegt. Im nächsten Abschnitt werden wir auf das erstellte XML-Layout von der Activity-Klasse aus zugreifen und es als Bildschirminhalt für die Start-Activity verwenden.
3. Das XML-Layout der Activity zuweisen
Da wir die XML-Layout Datei nun erstellt haben, können wir sie als Benutzeroberfläche für unsere Start-Activity nutzen. Momentan besteht die grafische Oberfläche der Start-Activity aus nur einem Textfeld, welches wir per Code (programmatisch) erstellt und als Bildschirminhalt festgelegt haben.
Wir werden nun das bisherige Layout der Start-Activity durch das in der XML-Layout Datei definierte ersetzen. Dazu öffnen wir die Klassendatei MainActivity.java
im Editor von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.zitate unseres Projekts.
Den bisherigen Quellcode lassen wir zu großen Teilen bestehen und nehmen nur einige kleine Änderungen darin vor. Der bereits überarbeitet Quellcode der MainActivity.java
ist unten aufgeführt:
MainActivity.java
package de.codeyourapp.zitate; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; //import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //TextView welcomeMessageTV = new TextView(this); //welcomeMessageTV.setText("Hello CodeYourApp World!"); //setContentView(welcomeMessageTV); setContentView(R.layout.activity_main); } }
Die Zeilen 5, 13, 14 und 15 haben wir auskommentiert, da sie nicht mehr benötigt werden. Durch sie hatten wir das bisherige UI-Layout erstellt und als Bildschirminhalt der Start-Activity festgelegt.
Neu hinzugekommen ist die Zeile 17, in der wir das neue UI-Layout aus der erstellten XML-Layout Datei laden. Dazu übergeben wir der setContentView() Methode die Resource-ID der erstellten Layout-Ressource.
Auf die entsprechende Ressource wird folgendermaßen im Code referenziert:
[<package_name>.]R.<resource_type>.<resource_name>
-
<package_name> ist der Name des Packages, in welchem sich die Ressource befindet. Wird bei Ressourcen aus dem eigenen Package nicht benötigt.
-
R ist die Ressourcen-Klassendatei, in der alle Ressourcen-IDs verwaltet werden. Sie sollte niemals von Hand verändert werden, da sie von dem aapt-Programm bei jedem Kompilieren des Projekts neu generiert wird. Jede Änderung würde daher beim nächsten Kompilieren automatisch überschrieben werden.
-
<resource_type> ist eine Unterklasse von R, die für den jeweiligen Ressourcen-Typ steht. In unserem Fall ist dies layout, da wir auf eine XML-Layout Datei zugreifen möchten.
-
<resource_name> ist entweder der Dateiname der Ressource (ohne Dateinamenserweiterung) oder der Wert des android:name-Attributs des XML-Elements (bei einfachen Werten, z.B. Strings). In unserem Fall ist es der Dateiname der XML-Layout Datei
activity_main.xml
ohne Dateiendung, also nur activity_main. Insgesamt ergibt sich daraus: R.layout.activity_main als Referenz zur Layout Datei.
In Android Studio sollte die MainActivity.java
Klassendatei nun wie folgt aussehen:
Nachdem wir das erstellte XML-Layout der Start-Activity unserer Android App als Benutzeroberfläche zugewiesen haben, können wir das neue Aussehen unserer Anwendung auf einem virtuellen Android Gerät im Android Emulator überprüfen. Dies werden wir als Nächstes durchführen.
4. Ausführen und Testen unserer Android App
Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen und überprüfen, ob unsere Start-Activity das erstellte XML-Layout als neue Benutzeroberfläche verwendet.
Unsere App starten wir über die Menüleiste, indem wir auf Run > Run 'app' klicken. Dabei ist unbedingt darauf zu achten, dass unser Hardware-beschleunigtes AVD Nexus 9 als Deployment Target über die Drop-Down Box (Markierung A) ausgewählt wurde:
Ab Android Studio 3.5 wird nun das AVD, auf dem unsere App ausgeführt werden soll, automatisch im Android Emulator gestartet. Danach wird unsere App auf das ADV installiert und gestartet. Bei älteren Android Studio Versionen erfolgte noch folgender Zwischenschritt, der in der unteren Akkordion-Box beschrieben wird.
Nun wird die Android App auf unserem erstellten AVD installiert und anschließend automatisch von Android Studio gestartet. Wenn alles funktioniert hat, ist unsere App jetzt im Emulator-Fenster gestartet worden.
In der unteren Abbildung ist unsere Android App auf dem virtuellen Gerät zu sehen:
Wir erhalten als Text folgenden String angezeigt: Hello CodeYourApp World! per XML-Layout. Zudem befindet sich jetzt unter dem Textfeld ein Button mit der Aufschrift PUSH ME, der jedoch noch keinerlei Funktionalität besitzt.
Zusammenfassung
Im theoretischen Teil dieser Lektion haben wir uns mit der visuellen Struktur der Benutzeroberfläche von Android Anwendungen beschäftigt. Dabei haben wir erfahren, wie man ein UI-Layout in Android per XML-Layout Datei definieren und in einer Activity-Klasse als Bildschirminhalt verwenden kann.
Anschließend haben wir im praktischen Teil dieser Lektion eine XML-Layout Datei erstellt und mit ihrer Hilfe das Aussehen unserer Start-Activity definiert. Die XML-Datei mussten wir in dem layout/ Ressourcen-Ordner unseres Android Projekts ablegen, welchen wir vorher noch erstellen mussten.
Am Ende dieser Lektion haben wir von der Klassendatei der Start-Activity aus auf die erstellte Layout Datei zugegriffen. Dazu haben wir die Datei MainActivity.java
im Editor geöffnet und Anpassungen an ihrem Quellcode vorgenommen. Abschließend haben wir unsere App im Android Emulator auf einem AVD zum Testen ausgeführt.
In der nächsten Lektion werden wir uns mit weiteren Ressourcen-Dateien unseres Android Studio Projekts beschäftigen. Dabei werden wir erfahren, warum es besser ist, bestimmte Inhalte in XML-Ressourcen Dateien auszulagern, als diese im Quellcode fest einzuprogrammieren.
Weiterführende Literatur
- Developer.android.com: UI Overview
- Developer.android.com: Declaring Layouts
- Developer.android.com: What is a Layout Resource?
- Developer.android.com: Accessing Resources in Android