5.1 Wozu?

Manchmal brauchen Sie je nach Kontext einen anderen Text oder ein anderes Bild an der gleichen Stelle. Zum Beispiel sollte je nach Spracheinstellung die Beschriftung eines Buttons deutsch oder englisch sein. Für ein Bild kann man sich verschiedene Ausschnitte oder ganz verschiedene Bilder (z.B. nach Tageszeit oder Wetterlage) vorstellen.

In Android wird daher eine Zwischenebene zwischen View und solchen Daten eingezogen. Das nennt sich Ressourcen (Vorsicht: auf Englisch nur mit einem "s", also resources).

Ressourcen als Zwischenebene

5.2 Ressourcen

Ressourcen sind also Daten, die je nach Kontext gewechselt werden. Außerdem sollen diese Daten leicht von Nicht-Programmierern (z.B. Übersetzer/innen oder Designer/innen) eingesehen und modifiziert werden können.

5.2.1 Arten

Eine Ressource ist z.B. ein Bild, das an einer bestimmten Stelle der App gezeigt werden soll. Je nach Kontext (z.B. verschiedene Endgeräte) möchte man eine andere Auflösung oder einen anderen Bildausschnitt zeigen. Konkret sind das mehrere Dateien, die sozusagen ein einziges "Bild" repräsentieren.

Eine Ressource kann auch ein Layout sein, das je nach Endgerät (Tablet vs Smartphone) oder Benutzereinstellung (z.B. einfach vs komplex) anders aussehen kann.

Eine Ressource kann auch ein String sein (also ein Text). Hier kann die gleiche Nachricht in verschiedenen Sprachen oder verschiedenen Formulierungen (formale Sprache vs lockere Sprache) vorliegen und je nach Kontext (Spracheinstellung oder Präferenzen des Users) angepasst werden. Auch hier wird eine einzige "Nachricht" mit mehreren Strings repräsentiert.

5.2.2 Speicherorte

Ressourcen müssen in bestimmten Verzeichnissen abgelegt werden, damit sie vom Compiler "eingesammelt" werden können. Alle Ressourcen befinden sich in

/res

Dort wiederum gibt es drei mögliche Unterverzeichnisse, die genau so benannt sein müssen:

/res/drawable
/res/layout
/res/values

Diese Unterverzeichnisse enthalten Bilder (drawable), Layouts (layout) und Strings/Farben/etc. (values), z.B.

/res/drawable/sunset.png
/res/values/strings.xml

Der Android-Ressourcencompiler durchläuft diese Verzeichnisse und produziert für jede Ressource einen entsprechenden Eintrag in der Klasse R.

5.3 Strings

Wie Sie wissen, können Sie bei Widgets wie Buttons oder Textfeldern den dargestellten Text mit der Eigenschaft text ändern. In XML sieht das so aus:

<Button
   ...
   android:text="Abschicken" />

In Android ist es allerdings gute Praxis, alle Texte als Ressource zu hinterlegen, damit Sie z.B. Ihre App sowohl für deutsche als auch für englischsprachige User darstellen können. Für die Sprache Englisch müssten Sie eigentlich schreiben:

<Button
   ...
   android:text="Submit" />

String als Ressource hinterlegen

Stattdessen lagern Sie die Texte in die Ressourcendateien aus und verwenden im Layout nur einen Platzhalter, den wir hier auch Schlüssel nennen. Wenn wir im obigen Beispiel den Schlüssel "button_submit" nennen, sieht das Layout so aus:

<Button
  ...
  android:text="@string/button_submit" />  

Diese zentrale Ressourcendatei für Strings wird immer automatisch mit angelegt:

res/values/strings.xml

In der Datei sehen Sie etwas wie

<resources>
    <string name="app_name">MyApp</string>
</resources>

Sie fügen eine neue String-Ressource mit einer neuen Zeile hinzu. Der Schlüssel kommt ins Attribut name, die Übersetzung dann zwischen die XML-Tags:

<resources>
    <string name="app_name">MyApp</string>
    <string name="button_submit">Submit</string>
</resources>

Wie wir oben schon gesehen haben, können Sie jetzt die String-Ressource per Schlüssel im Layout verwenden. Dazu muss man @string/ vor den Schlüssel der Ressource setzen:

<Button
  ...
  android:text="@string/button_submit" />  

Mehrsprachigkeit

Möchte man eine String-Ressource in mehreren Sprachen hinterlegen, öffnet man das obige File strings.xml und öffnet dann den Translations Editor (mit "open editor").

Translations Editor

Dort klicken Sie auf die Weltkugel und fügen die entsprechende Sprache hinzu.

Translations Editor, Weltkugel

Dadurch entsteht eine neue Datei strings.xml in einem anderen Unterverzeichnis, z.B. res/values-en für Englisch oder res/values-de für Deutsch. Sinnvoll ist es, für Deutsch ein solches Verzeichnis zu erstellen und im Standardordner die englischen Texte zu verwalten:

res/values/strings.xml
res/values-de/strings.xml

In der Datei "strings.xml" im neuen Ordner "values-de" speichern Sie dann alle Texte mit Schlüssel und deutscher Übersetzung ab:

<resources>
    <string name="app_name">MyApp</string>
    <string name="button_submit">Abschicken</string>
</resources>

Sie können natürlich beliebig viele Sprachen hinzufügen. Sie können die Funktionsweise in der Design-Ansicht des Layouts prüfen, indem Sie das "Language" Menü bedienen:

Sprache in der Vorschau einstellen

5.4 Bilder

Alle Bilder müssen im Ressourcenverzeichnis "drawable" abgelegt werden. Um unterschiedliche Varianten eines Bildes zu verwenden, legen Sie die Varianten mit dem gleichen Dateinamen, aber in speziellen Unterverzeichnissen ab.

Nehmen wir an, Sie verwenden ein Bild, das "sunset.png" heißt. Sie möchten aber für den Fall, dass das Smartphone im Querformat (landscape) gehalten wird, einen anderen Bildausschnitt verwenden. Dann erstellen Sie eine neue Datei mit dem entsprechenden Ausschnitt, lassen den Dateinamen gleich, aber speichern die Datei im Verzeichnis "drawable-land". Ihr Ressourcenverzeichnis sieht also wie folgt aus:

res/drawable/sunset.png
res/drawable-land/sunset.png

Sie können auch ein Verzeichnis für die Portrait-Orientierung anlegen:

res/drawable/sunset.png
res/drawable-land/sunset.png
res/drawable-port/sunset.png

Das erscheint aber in diesem Fall wenig sinnvoll, da das "normale" Bild dann ja nie verwendet wird (aber Speicherplatz wegnimmt). In der Praxis würde man also das "Standardbild" in den drawable-Ordner schieben und für die Spezialfälle entsprechende Ordner anlegen.

Ein Spezialfall kann auch eine Sprache sein, weil z.B. ein Schriftzug fest im Bild ist oder wenn man aufgrund des Kulturunterschieds unterschiedliche Motive verwenden möchte.

res/drawable/sunset.png
res/drawable-de/sunset.png

Hier würde man als "Standardbild" die häufigste Sprache annehmen (i.d.R. Englisch) und Spezialfälle in entsprechenden Verzeichnissen abhandeln.

Man kann die zwei Aspekte "Sprache" und "Orientierung" auch kombinieren:

res/drawable/sunset.png
res/drawable-de/sunset.png
res/drawable-de-land/sunset.png
res/drawable-land/sunset.png

Wichtig ist hier, dass die Reihenfolge der Kürzel (de, land, port, ...) ausschlaggebend ist. Sprache muss vor Orientierung angegeben werden.

Allgemein können Sie folgende Aspekte (in dieser Reihenfolge) berücksichtigen:

5.5 Übungen

(A) Mehrsprachiger Button

Schreiben Sie eine App mit einem Textfeld (TextView) und einem Button. Der Text und die Beschriftung des Buttons soll sich der eingestellten Sprache anpassen.

(B) Kontextsensitive Bilder

Schreiben Sie eine App mit einem Bildteil (ImageView) und einem Button. Je nach Orientierung des Endgeräts soll sich der Bildausschnitt verändern.

Bild in Portrait-Orientierung Bild in Landscape-Orientierung

Sie können die folgenden zwei Bilder verwenden (die Bilder stehen unter CC0-Lizenz). Noch besser: Sie verwenden ein eigenes Bild, das Sie entsprechend zuschneiden.

Beachten Sie, dass die Bilder, sobald sie in den korrekten Verzeichnissen sind, alle gleich heißen müssen.

(C) Kontextsensitive Bilder 2

Berücksichtigen Sie außer Orientierung auch noch die Sprache. Wenn wir davon ausgehen, dass die Standardsprache "Englisch" ist, fügen Sie noch Deutsch hinzu:

Bild in Portrait-Orientierung Bild in Landscape-Orientierung

Sie können zusätzlich zu den oberen zwei Bildern die folgenden Bilder verwenden (diese Bilder stehen ebenfalls unter CC0-Lizenz):

Beachten Sie, dass die Bilder, sobald sie in den korrekten Verzeichnissen sind, alle gleich heißen müssen.