Android-Programmierung GUI: Layout
Willemers Informatik-Ecke
Zurück zur Android-Hauptseite

Das Layout bestimmt die Anordnung der Kontrollelemente innerhalb einer Activity. Typischerweise wird das Layout bei der Android-Programmierung in einer XML-Datei festgelegt.

Eine Activity baut mit den Aufruf der Methode setContentView aus ihrer Handler-Methode onCreate heraus ihren Bildschirm auf und übergibt dazu ihre Layout-XML-Datei.

Ein Fragment ruft in seiner Handler-Methode onCreateView die Methode inflate auf, die mithilfe seiner Fragment-XML-Datei das Aussehen des Fragments bestimmt.

Die Layout-Datei

In der activity_xxx.xml wird das Layout der Activity xxx festgelegt. Die Bindung der XML-Datei an die Activity erfolgt aber von Java aus mit dem Aufruf von setContent aus der Methode onCreate heraus.
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_xxx);
Die XxxActivity hat eine XML-Datei die durch von der Vorgabe als RelativeLayout bestimmt wird.

XML-Definitionen

Größenverhältnisse

Für die Ausdehnung von Views oder Layouts werden gern folgende Standards verwendet:

Einheiten

Gängige Einheiten sind dp (Dichteunabhängiger Pixel) und sp (Textabhängig). Beide Einheiten führen dazu, dass Anwendungen auf verschiedenen Geräten keine Probleme bereiten, sondern etwa gleich aussehen.

Möglich sind auch die Einheiten mm, in, pt (Punkt - Eine Einheit aus dem Druckbereich). Allerdings sind diese nicht unabhängig von der Geräte-Hardware und sollten darum vermieden werden.

Identifikation

Jedes Element eines Layouts kann über eine ID gekennzeichnet werden. Das geschieht durch Hinzufügen einer android:id.
android:id="@+id/meinElement"
Diese ID ist wichtig, wenn man vom Java-Programm das Kontrollelement auslesen oder setzen will, aber auch, wenn das Verhältnis von Elementen innerhalb des Layouts definiert werden sollen:
app:layout_constraintStart_toEndOf= "@id/meinElement"

LinearLayout

In einem LinearLayout werden die Elemente immer untereinander oder nebeneinander angeordnet. Die Richtung wird durch das Orientation-Attribut bestimmt. Dessen Wert kann horizontal oder vertical sein.
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical" >

    ...

</LinearLayout>
Alle Kindelemente müssen android:layout_width und android:layout_height definieren:
<TextView
    android:layout_width  = "match_parent"
    android:layout_height = "wrap_content" />
Das LinearLayout wird aufgrund seiner einfachen Handhabung gern verwendet, um mit anderen Layouts verschachtelt zu werden. Hohe Verschachtelung macht den Neuaufbau des Bildschirms aufwändig. Insofern kann es sich aus aus Performance-Gründen lohnen, komplexere Layouts zu verwenden.

RelativeLayout

Im RelativeLayout werden die Elemente im Verhältnis zu anderen Elementen angelegt, also beispielsweise unter einem Button oder links von einer TextView.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

...
    <EditText
        android:id="@+id/edSpielername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/spielerliste"
        android:singleLine="true"
        android:layout_toRightOf="@+id/textView"
        android:layout_toEndOf="@+id/textView"
        />
...

</RelativeLayout>
In den Elementen können folgende Relationen angegeben werden.
android:layout_above Das Element liegt über dem anderen Element.
android:layout_below Das Element liegt unter dem anderen Element.
android:layout_toLeftOf Das Element liegt links von dem anderen Element.
android:layout_toRightOf Das Element liegt rechts von dem anderen Element.
android:layout_toStartOf Das Element richtet sich nach dem Anfang dem anderen Elements aus. Die Elemente beginnen also in der gleichen vertikalen Position.
android:layout_toEndOf Das Element richtet sich nach dem Ende des anderen Elements aus.

ConstraintLayout

Das ConstraintLayout organisiert seine Elemente durch Constraints, die das Verhältnis von Elementen beschreiben. Auf diese Weise ist es noch etwas flexibler als das RelativeLayout.
<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    ...

</android.support.constraint.ConstraintLayout>
Die Elemente können Beziehungen zwischen seinen Kanten Start oder End bzw. Top zu Kanten (Bottom zu Start oder End bzw. Top) anderer Elemente, auch der des Elternelements (parent) definieren.

app:layout_constraintStart_toStartOf= "parent"
app:layout_constraintStart_toEndOf= "@id/cancel_button"
app:layout_constraintTop_toTopOf= "parent"
app:layout_constraintTop_toBottomOf= "@id/recyclerView"
app:layout_constraintEnd_toEndOf= "parent"
app:layout_constraintBottom_toTopOf= "@id/ok_button"
app:layout_constraintBottom_toBottomOf= "parent"

Verschachteln von Layouts

Layouts können verschachtelt werden. So kann innerhalb des RelativeLayouts auch ein oder mehrere andere Layouts liegen, wie hier ein LinearLayout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
    <Button
        android:id="@+id/bermudaview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
...
</LinearLayout>
Innerhalb des LinearLayouts liegen die Kontrollelemente, wie hier ein Button.

Buttons nebeneinander mittig ausrichten

Damit Buttons in der Horizontalen den Platz (halbwegs) gleichmäßig ausnutzen, legt man ein horizontales LinearLayout an. Darin wird über ein Weight bestimmt, welcher Button breiter werden muss als die anderen. Sind die Weights alle gleich, richten sie sich gleichmäßig aus.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".SpielerActivity">

    ...
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/virtuell"
        android:id="@+id/ckAutomat"
        android:layout_below="@+id/ed...."
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="3"
        android:layout_below="@+id/ckAutomat"
        >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/change"
        android:id="@+id/btChange"
        android:layout_weight="1"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/add"
        android:layout_weight="1"
        android:id="@+id/btAdd"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/del"
        android:id="@+id/btDel"
        android:layout_weight="1"
        />
    </LinearLayout>

</RelativeLayout>