Stand: 21.07.2018
3.1 Einführung
In diesem Kapitel geht es ausschließlich um das Visuelle, also die grafische Benutzerschnittstelle. Wie legt man die Anordnung, also das Layout der verschiedenen Komponenten (Textfelder, Buttons, Slider etc.) fest?
Was bei allen grafischen Oberflächen aber die große Herausforderung ist: Wie gehe ich mit der Tatsache um, dass es verschieden große Screens gibt und dass die Screen entweder horizontal (Landscape) oder vertikal (Portrait) orientiert sein kann?
3.1.1 Objekte
In objektorientierten Programmiersprachen sind sichtbare grafische Komponenten wie Buttons und Textfelder Java-Objekte, also Instanzen von Java-Klassen. Das ist aus Sicht des Programmierers intuitiv und aus Sicht der Softwaretechnik gutes Design.
Von XML zu Java (inflate)
Wir wissen aus dem vorigen Modul, dass unsere Komponenten und Layouts mit Hilfe einer XML-Datei (z.B. activity_main.xml) festgelegt werden. Wie bringt man dieses XML mit Java zusammen?
Die Antwort steht in der Datei MainActivity.java
. Dort sehen wir:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
}
Relevant ist hier der Aufruf von setContentView
. In dieser Zeile bezieht Java mit Hilfe der Klasse R zunächst den ID der Layoutdatei, holt sich dann diese Datei und überführt das XML in Java-Objekte.
Diesen Vorgang nennt man auch inflate (engl. für aufblasen). Man kann mit Hilfe der Klasse LayoutInflater
auch programmatisch beliebige XML-Layouts in Java überführen, wie wir an anderer Stelle noch sehen werden. Hier ist der Vorgang in der Methode setContentView
enthalten.
Nicht-sichtbare Layout-Objekte
Wichtig ist, dass es auch nicht-sichtbare Objekte gibt, die eine reine Layout-Funktion haben. Diese Objekte dienen als Container, die andere Objekte (z.B. Textfelder und Buttons) enthalten und bestimmen, wo diese enthaltenen Objekte darzustellen sind.
Ein Beispiel ist ein Layout-Objekt vom Typ LinearLayout
, welches verschiedenen sichtbare Komponenten enthalten kann und diese einfach entlang einer Linie anordnet. Hier z.B. einmal vertikal, einmal horizontal:
Diese Layout-Objekte können sowohl sichtbare als auch nicht-sichtbare Komponenten enthalten.
3.1.2 Baumstruktur
Alle sichtbaren Objekte (z.B. Textfelder, Buttons) sind Instanzen von Unterklassen der Klasse View
. Solche Komponenten werden auch Widgets genannt.
Alle nicht-sichtbaren (Layout-) Objekte sind Instanzen von Unterklasen der Klase ViewGroup
. Da ein Layout-Objekt auch weitere Layout-Objekte beinhalten kann, können wir komplexe Layouts durch Verschachtelung herstellen.
Hier sieht man einfach ein vertikales LinearLayout (lila) und, darin enthalten, ein horizontales LinearLayout (gelb).
Ein Layout besteht also aus einer Verschachtelung von Views und ViewGroups. Zusammen ergibt sich eine Baumstruktur:
Google empfiehlt aus Performance-Gründen, die Verschachtelungstiefe möglichst klein zu halten.
Eine
- ViewGroup: enthält entweder Views oder ViewGroups
- View: steht am "Ende" eines Asts und kann nichts weiter enthalten
An der Spitze des dargestellten Baums steht immer eine ViewGroup. Man nennt diese auch das Wurzel-Layout (engl. root layout).
Zwei sehr häufige Layouts sind LinearLayout und RelativeLayout. Seit neuestem wird ein weiteres Layout als das Layout verwendet: das ConstraintLayout.
3.1.3 Grafischer Editor
Das Layout wird mit Hilfe einer XML-Datei spezifiziert. Android Studio bietet parallel dazu einen grafischen Editor an. Man kann dann bequem von der XML-Datei auf den Editor umschalten und umgekehrt.
Um das Layout zu bearbeiten, geht man auf das Layout-XML, z.B. res/layout/activity_main.xml
. Normalerweise sieht man zunächst den grafischen Editor:
Links unten sieht man zwei "Reiter" (Tabs) mit den Bezeichnern Design und Text. Dort können Sie zwischen der XML-Sicht (Text) und der grafischen Sicht (Design) umschalten.
Sie sollten auf jeden Fall mit beiden Sichten vertraut sein. Viele Dinge kann man schneller und übersichtlicher in der Text-Sicht lösen. Dort kann man auch schnell Komponenten aus anderen Projekten mit einem einfachen Copy-n-Paste kopieren.
3.2 Komponenten/Widgets
Für unsere ersten Beispiele werden wir zwei sichtbaren Komponenten besonders häufig nutzen: Button und TextView. TextView ist ein Feld, in dem Text angezeigt wird. Er kann nicht vom Benutzer editiert werden (das wäre EditText).
Sie finden diese und anderen Komponenten in der Design-Ansicht Ihres Layouts (z.B. activity_main.xml) in dem Teilfenster palette:
In der Design-Ansicht können Sie die Komponenten einfach per Drag'n Drop nach links auf die Screen ziehen. Sehen Sie sich im Anschluss immer in der Text-Ansicht an, wie genau die Komponente konfiguriert ist.
3.2.1 Button und TextView
Button und TextView sind zunächst mal Java-Klassen. Es lohnt sich ein Blick in die offizielle Dokumentation (kurz API) der Klassen Button und TextView. Dort finden Sie alle XML-Eigenschaften (fürs Layout) und alle Java-Methoden für den programmatischen Zugriff.
(Interessant ist z.B., dass Button eine Unterklasse von TextView ist. Warum? Ein Button enthält ja auch Text - die Beschriftung - und hat zusätzliche Funktionalität, nämlich dass er anklickbar ist. Also "erweitert" die Klasse Button einfach die Klasse TextView.)
Button in XML und Java
In der Text-Ansicht sieht ein Button z.B. so aus:
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="230dp"
tools:layout_editor_absoluteY="34dp" />
Die Eigenschaften layout_editor_absoluteX
und layout_editor_absoluteY
sollten Sie immer direkt löschen, denn dies sind absolute Positionierungen, die in einer Welt von unterschiedlichen Screengrößen nicht sinnvoll sind. Allein wenn Sie die Orientierung ändern (Portrait zu Landscape), führen absolute Positionsangaben regelmäßig zu Screen-Salat.
Mit der Eigenschaft text
können Sie die Beschriftung des Buttons festlegen. Enorm wichtig ist auch die Eigenschaft id
. Über den ID greifen Sie in Java (z.B. in MainActivity.java) auf den Button zu:
Button b = findViewById(R.id.button3);
Außerdem werden Layout-Bezüge zwischen den Komponenten (in RelativeLayout und ConstraintLayout) über den ID hergestellt.
Wenn Sie den ID ändern, sollten Sie das mit Hilfe von Refactoring tun (Rechtklick Refactor > Rename...), damit Querbezüge in Java und im Layout nicht zerstört werden.
Alles, was Sie im XML festlegen, können Sie auch in Java "programmatisch" kontrollieren. Sie können z.B. die Beschriftung festlegen oder ändern:
Button b = findViewById(R.id.button3);
b.setText("Click me");
Sie können den Button auch deaktivieren, d.h. er bleibt sichtbar, aber ist nicht mehr anklickbar (i.d.R. wird es ausgegraut):
b.setEnabled(false);
TextView in XML und Java
Ein TextView sieht in der Text-Ansicht z.B. so aus:
<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" />
Interessant zu sehen ist hier, dass manchmal kein ID vorliegt. Wenn Sie aber auf diesen Text zugreifen wollen, benötigen Sie einen. Also fügen Sie selbst einen hinzu, achten Sie dabei darauf, dass Sie ein @+id
voranstellen:
<TextView
android:id="@+id/textTitle"
... />
Interessante Eigenschaften sind z.B. Schriftgröße, Stil (fett, kursiv), Farbe oder Alignierung (links, rechts, zentriert). Diese stellen Sie am besten in der Design-Ansicht in der rechten Leiste Attributes ein (Sie müssen die entsprechende Komponente zuvor in der Screen-Vorschau anklicken).
Im XML sieht das dann so aus und kann natürlich auch hier editiert werden:
<TextView
...
android:textAlignment="center"
android:textColor="@android:color/darker_gray"
android:textSize="18sp"
android:textStyle="bold"
... />
(Die Größeneinheit "sp" wird im nächsten Abschnitt erläutert.)
Auch hier können Sie die Komponente in Java programmatisch kontrollieren:
TextView tv = findViewById(R.id.textTitle);
tv.setText("Welcome to Android");
tv.setTextSize(20);
tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
3.2.2 Texteingabe, Schalter, Bilder
Wir stellen noch ein paar Komponenten vor, die für Ihre ersten Apps noch von Interesse sein könnten.
EditText ist ein Textfeld für die Eingabe von Text durch den Benutzer. In der Design-Ansicht gibt es dafür zahlreiche Kategorien wie "Plain Text" oder "Multiline Text", aber in der Text-Ansicht sehen Sie, dass es sich immer um die Klasse EditText handelt mit kleinen Unterschieden in den Eigenschaften.
CheckBox ist ein Markierungsfeld, das angekreuzt/angehakt ist oder eben nicht. Den Anfangszustand legen Sie im XML so fest:
android:checked="true"
In Java haben Sie eine entsprechende Methode:
CheckBox cb = findViewById(R.id.checkBox);
cb.setChecked(true);
ToggleButton ähnelt der CheckBox, sieht aber aus wie ein Button, der eine Markierung hat, die anzeigt, ob der Button im Zustand EIN oder AUS ist. Auch hier legt man mit der Eigenschaft checked
fest, wie der Anfangszustand ist.
ImageView zeigt eine Bilddatei, z.B. im jpg- oder png-Format. Sie müssen die Datei zunächst in das Ressourcenverzeichnis res/drawable
Ihres Projekts speichern. Achten Sie darauf, dass der Dateiname keine Bindestriche/Minuszeichen enthält und nicht mit einer Zahl beginnt! Wenn Sie dann in der Design-Ansicht einen ImageView
auf die Screen ziehen, können Sie Ihr Bild auswählen.
Wir werden uns noch in den Modulen Ressourcen und Layout II mit dem Thema Bild auseinander setzen.
3.2.3 Pixeldichte, dp und sp
Mit immer besseren Auflösungen hat sich für Entwickler mobiler Anwendungen und für Webentwickler ein Problem ergeben, nämlich: Wie gebe ich die Größe und Abstände meiner Komponenten an? Früher hat man alles in "Pixel", also in Bildschirmpunkten, gemessen. Ein Kreis mit 100 Pixeln Durchmesser war auch auf allen Geräten ganz ungefähr gleich groß bzw. gleich gut sichtbar. Mit den neuen, extrem hohen Auflösungen war dieser Kreis aber teilweise kaum noch sichtbar. Die neuen Geräte hatten eine zu hohe Pixeldichte, also zu viele Pixel auf kleinem Raum, oft auch gemessen in dpi (dots per inch).
Die Lösung war, neue Einheiten zu entwickeln, die auf allen Geräten eine mehr oder minder vergleichbare Größe darstellten. Bei Android heißt diese Einheit density-independent pixels oder kurz dp. Ein "dp" soll einem Pixel auf einem Display "mittlerer" Auflösung entsprechen, genauer gesagt einem Display mit 160 dpi. Beachten Sie, dass bei anderen Sprachen und Framework diese Einheit i.d.R. anders heißt.
Kurz: Verwenden Sie für Höhen, Breiten und Abstände immer die Einheit dp.
Bei Schriften verwenden Sie nochmal eine andere Einheit, nämlich die scale-independent pixels oder kurz sp. Diese Einheit ist im Grunde die gleiche wie dp, aber passt sich zusätzlich an die vom Benutzer verstellbare Grundschriftgröße an. Das heißt, wenn die Grundschriftgröße "normal" ist, entspricht sp der Einheit dp. Wenn der User die Grundschriftgröße erhöht, erhöhen sich automatisch alle sp-Werte (aber natürlich nicht die dp-Werte). Eine sinnvolle Trennung also.
Kurz: Verwenden Sie für Schrift bzw. Texte immer die Einheit sp.
(Lesen Sie dazu auch den Artikel über Screen Densities.)
3.3 LinearLayout
LinearLayout packt alle Komponenten in eine horizontale oder vertikale Reihe.
Um LinearLayout auszuprobieren, erstellen Sie ein neues Projekt und gehen in die Textansicht von activity_main
.
<?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.michaelkipp.linearlayoutsimple.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>
Jetzt ersetzen Sie ConstraintLayout durch LinearLayout. Löschen Sie am besten mit der BACKSPACE-Taste, dann wird der Text sowohl im öffnenden als auch im schließenden Tag ersetzt. Sie ersetzen
android.support.constraint.ConstraintLayout
durch
LinearLayout
D.h. Sie benötigen für LinearLayout keinen "Pfad".
Fügen Sie jetzt noch die Eigenschaft "orientation" mit dem Wert "vertical" hinzu.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:orientation="vertical">
Außerdem können Sie noch alle Angaben, in denen "tools" vorkommt, löschen. Achten Sie darauf, dass die spitzen Klammern erhalten bleiben:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
3.3.1 Layouten mit Verschachtelung
Prinzipiell layouten Sie mit LinearLayout, indem Sie mehrere LinearLayout-Objekte verschachteln. Hier sehen Sie ein einfaches Beispiel mit zwei Layout-Objekten:
Sie können mit Hilfe von Verschachtelung erstaunlich komplexe Layouts anfertigen. Hier ein Beispiel:
Wenn Sie sich ein beliebiges Fenster anschauen, egal ob auf dem Handy oder auf dem Laptop, dann können Sie für die meisten Fenster eine Reihe von LinearLayout-Container einzeichnen und das Fenster i.d.R. auch in Android nachbauen.
3.3.2 Schritt-für-Schritt-Beispiel
Wie bekommt man ein verschachteltes Layout in Android Studio hin? Nehmen wir an, Sie haben Ihr ConstraintLayout bereits ersetzt durch ein LinearLayout, d.h. Ihre Layoutdatei sieht so aus:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
Jetzt können Sie in der Design-Ansicht weitere Layout-Container hinzufügen. Das tun Sie am besten im Component Tree-Fenster links unten von der Vorschau:
Wählen Sie im Palettenfenster den Reiter "Layout" und ziehen Sie zwei Mal ein LinearLayout (horizontal) in den Component Tree in das bestehende LinearLayout hinein. Das müsste dann so aussehen:
Damit wir in der Vorschau auch was sehen, müssen wir sichtbare Komponenten ins Design ziehen. Auch hier arbeiten wir im Component Tree. Wählen Sie in der Palette den Reiter "Widgets" und ziehen Sie drei Buttons in das obere horizontale LinearLayout und dann zwei Buttons in das untere horizontale LinearLayout.
Sie sehen nur die obere Reihe Buttons! Warum? Das obere LinearLayout hat als Grundeinstellung layout_height:match_parent
, d.h. der Container versucht, die ganze Screen zu beanspruchen und verdrängt das untere LinearLayout.
Die Lösung ist, bei beiden (horizontalen) LinearLayouts die layout_height
auf wrap_content
zu stellen:
Sie sehen, dass zwar viele Layouts möglich sind, dass Sie aber evtl. viel Zeit damit zubringen, die richtigen Feineinstellungen zu finden. Das hilft - wie immer - nur viel Praxis!
3.3.3 Einstellmöglichkeiten
Orientierung
Was bedeutet das alles? Die orientation bestimmt, ob die enthaltenen Elemente horizontal oder vertikal angeordnet werden.
Also so...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:orientation="vertical">
... oder so:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:orientation="horizontal">
Layoutbreite und Layouthöhe
Bei layout_width und layout_height gibt es zwei Möglichkeiten:
- match_parent: es wird "so weit wie möglich", d.h. bis an die Grenze der umgebenden Komponente (parent), sich ausgedehnt
- wrap_content: es wird "so weit wie nötig", d.h. so weit, wie es der Inhalt (Text, Bild) erfordert, sich ausgedehnt
Ersetzen Sie den TextView durch zwei Buttons:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Ein weiterer Button" />
</LinearLayout>
Sie sehen, dass beim ersten Button "match_parent" und beim zweiten Button "wrap_content" eingestellt ist:
Ausrichtung
Über die Eigenschaft gravity können Sie die Ausrichtung der enthaltenen Komponenten einstellen:
<LinearLayout
...
android:gravity="center"
android:orientation="vertical">
Entsprechend sehen Sie:
Sie können mit gravity alle Komponenten oben, unten, links, rechts oder eben zentriert ausrichten.
Gewichtung
Bei den Widgets können Sie die Gewichtung der Komponenten über layout_weight einstellen. Diese Werte sind relativ zu einander. In diesem Beispiel bekommt der erste Button Gewicht 2, der zweite Gewicht 1, d.h. der erste bekommt 2 von insgesamt 3 Anteilen Platz (also 2/3 des Raums), der zweite entsprechend nur 1/3.
<Button
...
android:layout_weight="2"
android:text="Button 1" />
<Button
...
android:layout_weight="1"
android:text="Ein weiterer Button" />
Zwei weitere enorm wichtige Eigenschaften von sichtbaren Komponenten sind Margin und Padding.
Margin und Padding
Die Margin bestimmt den Außenabstand, d.h. den Abstand vom Rand der Komponente bis zum Rand des umgebenden Containers:
<Button
...
android:layout_margin="20dp"
... />
Man kann das auch für bestimmte Seiten spezifizieren:
<Button
...
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
... />
Das Padding ("Füllung") bestimmt den Innenabstand, d.h. den Abstand vom Rand der Komponente zum Inhalt (Text, Bild) hin. Hier für den unteren Button:
<Button
...
android:padding="30dp"
android:text="Ein weiterer Button" />
Text
Natürlich können Sie bei Widgets wie Buttons oder Textfeldern auch den Text einstellen. Hier können Sie einfach im XML die Eigenschaft text ändern:
<Button
...
android:text="Abschicken" />
3.4 RelativeLayout
Beim LinearLayout geht es darum, wie die enthaltenen Komponenten innerhalb des Containers angeordnet werden. Ein komplexes Layout erreicht man durch Verschachtelung.
Beim RelativeLayout versucht man, die enthaltenen Komponenten durch Beziehungen (engl. relations) soweit zu spezifizieren, dass Android sie sinnvoll positionieren kann. Da solche Beziehungen die mögliche Position einer Komponente einschränkt (engl. to constrain), kann man eine solche Beziehung auch Constraint nennen.
Im einem RelativeLayout-Objekt kann man einerseits zwei enthaltene Komponenten A und B zueinander in Beziehung setzen, z.B.
- A und B sollen am oberen Rand miteinander aligniert sein oder
- B soll rechts von A stehen
Andererseits kann man eine enthaltene Komponente A zu dem RelativeLayout-Objekt R selbst (also dem Container von A) in Beziehung setzen, z.B.
- A soll am linken Rand von R stehen oder
- A soll im Zentrum von R sein
Um die Beziehungen/Constraints zu definieren, ist der jeweilige ID einer Komponente (Button, TextView etc.) wichtig. Diesen finden Sie im XML in der Form "@+id/". Wenn Sie keinen sehen, müssen Sie selbst diese Eigenschaft hinzufügen.
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
Im folgenden sehen wir uns die möglichen Beziehungen mit Beispielen an. Eine Tabelle mit allen Constraints finden Sie bei Tutorialspoint.
3.4.1 RelativeLayout erstellen
Wenn Sie ein frisches Projekt mit einem ConstraintLayout haben, dann müssen Sie das Layout-File dahingehend ändern, dass Sie sehen:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
...
</RelativeLayout>
Sie dürfen die folgenden Beziehungen natürlich nur auf Komponenten anwenden, die sich innerhalb dieser Klammern befinden.
Natürlich dürfen Sie auch RelativeLayout und LinearLayout ineinander verschachteln. Die Beziehungen müssen aber eben in einem RelativeLayout-Container sein.
3.4.2 Beziehungen zwischen enthaltenen Komponenten
Wir beschäftigen uns zunächst mit den Beziehungen zwischen zwei enthaltenen Komponenten A und B. Diese Komponenten können beliebige Views sein, also z.B. Buttons, Bilder oder Textfelder.
Man kann zur Alignierung der Kanten folgende Constraints definieren. Die eigentlichen Eigenschaften heißen z.B. android:layout_alignTop. Hier ein Beispiel:
<Button
android:id="@+id/button1"
... />
<Button
android:id="@+id/button2"
...
android:layout_alignStart="@+id/button1"/>
In den folgenden Grafiken sind der Übersichtlichkeit halber nur Kurzformen der Eigenschaftsbezeichner zu sehen. Statt "alignStart" heißt es also eigentlich "android:layout_alignStart".
Sie können zwei Komponenten also anhand einer Kante ausrichten/alignieren:
Man kann spezifizieren auf welcher Seite eine Nachbarkomponente steht. Den Abstand kann man dann mit Margin setzen.
Beispiel
Wir schauen uns ein Beispiel mit drei Textkomponenten an.
Wenn Sie eine Komponente ohne Beziehungen einsetzen, werden diese einfach links oben im jeweiligen Layout-Objekt positioniert.
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Es war einmal"
android:textSize="30sp" />
Jetzt können Sie mit Hilfe des Außenabstands die Komponente leicht verschieben:
<TextView
...
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
... />
Jetzt fügen wir zwei weitere Textfelder hinzu.
Diese sollen untereinander (below) und linksbündig (alignStart) positioniert sein. Wir definieren also die zwei Texte relativ zum ersten bzw. zum zweiten:
<TextView
android:id="@+id/textView"
...
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:text="Es war einmal" />
<TextView
android:id="@+id/textView2"
...
android:layout_alignStart="@+id/textView"
android:layout_below="@+id/textView"
android:text="in einer Galaxy" />
<TextView
android:id="@+id/textView3"
...
android:layout_alignStart="@+id/textView2"
android:layout_below="@+id/textView2"
android:text="weit, weit entfernt" />
Beachten Sie die Bedeutung der IDs im Code, um die Beziehungen definieren zu können.
3.4.3 Beziehungen zur Elternkomponente
Für eine Komponente K ist die Elternkomponente die Komponente "oben drüber", also der Container, der K enthält. Das ist in diesem Fall unser RelativeLayout-Objekt R.
Wir können K an den Rand der Elternkomponente R stellen:
Wir können auch innerhalb von R zentrieren:
Beispiel
Will man z.B. einen Button an den unteren Rand der Screen setzen wollen...
...würde man schreiben
<Button
...
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50dp"
... />
Die Schritte, um obiges Layout zu erreichen, sind also:
- setze den Button an den unteren Rand (alignParentBottom)
- zentriere ihn in der Horizontalen (centerHorizontal)
- lege einen festen Abstand zum unteren Rand fest (marginBottom)
Natürlich können Sie auch innerhalb eines RelativeLayout ein LinearLayout verwenden und umgekehrt.
3.5 Übungen
(A) LinearLayout
Realisieren Sie folgendes Layout und beachten Sie auch die Hinweise unten. Verwenden Sie dabei folgende Bestandteile (teils mehrfach):
- LinearLayout
- Button
- Textfeld (TextView)
- Bildfeld (ImageView)
In der Landscape-Orientierung soll das ganze dann so aussehen:
Hinweise
- Sie müssen mehrere LinearLayout-Objekte verwenden (verschachtelt)
- Setzen Sie die Breite (layout_width) von Textfeld und Bildfeld auf einen fixen Wert, z.B. "100dp"
- Wenn Sie Komponenten nicht sehen, überlegen Sie bei der Höhe, wo "match_parent" und wo "wrap_content" stehen sollte
- Zur Positionierung der Buttons ziehen Sie gravity in Betracht (siehe Abschnitt "Ausrichtung")
(B) RelativeLayout
Verwenden Sie RelativeLayout, ein Textfeld und zwei Buttons, um folgendes Layout zu realisieren:
In der Landscape-Orientierung soll das ganze dann so aussehen: