Material Design und Themes
Dauer: 30 Minuten
Scaffold
für LayoutsFloating Action Button
imScaffold
- Theme mit Dark Mode
Ziel: Apps mit Material Design gestalten
Mit dem Material Design (https://material.io ) hat Google eine „Designsprache“ für Apps auf verschiedenen Plattformen definiert (Web, Android, usw.).
Die beiden Composables Text
und Checkbox
in unserer
App sind Beispiele für vordefinierte Komponenten des
Material Designs.
Hier betrachten wir Scaffold
für Layouts,
FloatingActionButton
als Beispiel für eine weitere
Komponente, die im Scaffold definiert wird und behandeln
kurz das Thema Themes (insbesondere Dark Mode).
Scaffold
für Layouts
Die Scaffold
-Komponente ist ein Container für das
gesamte Layout einer App, die im Material Design
definiert werden soll. Scaffold kann z.B. eine App-Bar
und den Hauptbereich der App enthalten.
Wir haben Scaffold bereits nach der Erstellung unseres
Projekts in der MainActivity
gesehen. Für die
schrittweise Entwicklung unserer App haben wir Scaffold
zunächst entfernt. Nun fügen wir unserer App wieder ein
Scaffold hinzu, indem wir TodoList
mit Scaffold
in
setContent
umgeben:
enableEdgeToEdge()
setContent {
Scaffold { innerPadding ->
TodoList(modifier = Modifier.padding(innerPadding))
}
}
Zusätzlich haben wir enableEdgeToEdge()
hinzugefügt, um die App an den
Bildschirmrand zu erweitern. Dies war ebenfalls Teil des Templates beim
Erstellen der App und wird für ältere Android-Versionen empfohlen (Default ab Android 15 ). Durch das Hinzufügen von
Scaffold
erscheint die App-Bar oben im Emulator passend zum App-Design.
Im Oktober 2025 fehlt enableEdgeToEdge()
in dem Einstiegs-Codelab der offiziellen Android-Dokumentation: https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app
Scaffold gibt einen Parameter innerPadding
an die
Lambda-Funktion bzw. die enthaltenen Composables weiter,
der für die Innenabstände des Hauptbereichs verwendet
werden kann. Damit sich diese bei uns auswirkt,
müssen wir diesen Parameter in TodoList
entgegennehmen
und an Column
weitergeben:
@Composable
fun TodoList(modifier: Modifier = Modifier) {
Column(modifier) {
Todo("Einkaufen")
Todo("Android lernen")
Todo("Sport machen")
}
}
TodoList(modifier: Modifier = Modifier)
definiert einen
optionalen Parameter modifier
mit dem Standardwert
Modifier
(falls nichts übergeben wird). Dieser wird an
Column
weitergegeben.
Diese Änderung führt zu einer kleinen Verschiebung der
Todos im Emulator, da die Innenabstände des Hauptbereichs,
die durch innerPadding
definiert werden, jetzt
berücksichtigt werden.
Dies kann durch Auskommentieren bzw. Entfernen und Hinzufügen
von modifier
in Column(…)
im Emulator nachvollzogen werden.
Das „Durchreichen“ von Modifiers ist ein häufiges Muster in Compose und erleichtert die Wiederverwendung und Wartbarkeit von Composables.
Guide zu Scaffold: https://developer.android.com/develop/ui/compose/components/scaffold
FloatingActionButton
im Scaffold
Für die Erstellung eines neuen Todos wollen wir einen
FloatingActionButton
hinzufügen. Dafür gibt es die Möglichkeit,
diesen direkt als Parameter im Scaffold
zu definieren:
setContent {
Scaffold(floatingActionButton = {
FloatingActionButton(
onClick = { /* todo… */ },
) {
Text("+")
}
}) { innerPadding ->
TodoList(modifier = Modifier.padding(innerPadding))
}
}
Die onClick
-Funktion ist noch leer, da wir das Verhalten des Buttons
erst später implementieren werden.
Zunächst haben wir nur ein „+“-Zeichen als Text im Button. Im Material Design wird die Verwendung von Icons empfohlen.
Neu im Oktober 2025: In der offiziellen Android-Dokumentation wird inzwischen von der Verwendung der bisherigen Icon-Bibliothek abgeraten, u.a. da diese nicht mehr weiterentwickelt wird (siehe https://developer.android.com/develop/ui/compose/graphics/images/material ).
Empfohlen wird stattdessen die Verwendung von Vektor-Assets aus den Google Font Icons, wie im obigen Link erwähnt und in den folgenden Schritten beschrieben.
In den Google Font Icons suchen wir uns unter https://fonts.google.com/icons ein passendes Icon aus. In unserem Fall ist dies das „add“-Icon (das plus-Zeichen). Wir öffnen das Icon im Browser und wählen dort das „Android“-Tab aus, um die XML-Datei für das Vektor-Asset herunterzuladen.
In Android Studio öffnen wir den Resource Manager über das Tools
-Menü oder den Eintrag in der linken Seitenleiste. Dort fügen wir die
heruntergeladene XML-Datei per Drag-and-Drop ein. Die Schritte im
nun erscheinenden Dialog können so übernommen und bestätigt werden.
Im Code der MainActivity
können wir den FAB nun mit dem Icon
ausstatten:
FloatingActionButton(
onClick = { /* todo… */},
) {
Icon(
painter = painterResource(R.drawable.add_24px),
contentDescription = "Neues Todo erstellen"
)
}
Stand Oktober 2025: Im XML wird ein Attribut für die Farbe definiert (“), welches zu einem Compile-Fehler führt.
Wir beheben dies dadurch, dass wir unserem Projekt die AppCompat
-Bibliothek hinzufügen, welche Kompatibilitätsschichten für ältere Android-Versionen bereitstellt. Dadurch können wir den Fehler beheben.
→ Hoffentlich ist dies in Zukunft nicht mehr nötig.
Vorgehen:
- In
app/build.gradle
imdependencies
-Block folgende Zeile hinzufügen (ggf. Version mitAlt-Enter
in Android Studio aktuell halten):implementation("androidx.appcompat:appcompat:1.7.1")
- Mit dem Tooling in Android Studio (
Alt-Enter
) können wir diese Abhängigkeit auch passend zu der bisherigen Implementierung unter Verwendung der Versionsdeklaration inlib.versions.toml
einbinden. - Dann oberhalb des Editors in der gelben Leiste auf
Sync Now
klicken, um die Abhängigkeiten zu aktualisieren.
Nun sollte der FAB im Emulator mit dem Icon angezeigt werden.
Hier sehen wir ein Beispiel für die Herausforderung, aktuelle Best Practices in der sich schnell entwickelnden Android-Welt zu verfolgen. Eigene Recherchen sind hier unerlässlich.
Es gibt im Material Design auch einen ExtendedFloatingActionButton
, der zusätzlich
zum Icon oder ausschließlich einen Text enthalten kann: https://m3.material.io/components/extended-fab
Theme mit Dark Mode
Android Apps haben im Material Design ein Theme, das die
Farben und Schriftarten definiert. Das Theme wird beim
Erstellen der App automatisch erzeugt und wird mit
<App-Name>Theme
bezeichnet. Bei uns ist dies TodosAndroidTheme
,
weil die App TodosAndroid
heißt.
Bitte Namen des Themes anpassen, falls die App anders heißt.
Wir fügen das Theme in der MainActivity
mit TodosAndroidTheme
hinzu, indem wir die Composables damit umgeben:
setContent {
TodosAndroidTheme {
Scaffold(floatingActionButton = {
FloatingActionButton(
onClick = {},
content = { Icon(Icons.Filled.Add, contentDescription = "Todo erstellen") }
)
}) { innerPadding ->
TodoList(modifier = Modifier.padding(innerPadding))
}
}
}
Mit dieser Änderung wird das Theme auf die gesamte App angewendet und
wir erhalten automatisch die Unterstützung für Dark Mode in unserer
App. Dies kann durch Setzen von Dark Theme
in den Display-Einstellungen
im Emulator getestet werden (oder im Code durch Änderung von ui/Theme.kt
).
Im Ordner ui/theme
befinden sich die Definitionen für die
Farben und Schriftarten der Themes in Kotlin-Code.
Links
Material Components: https://developer.android.com/develop/ui/compose/components
Design in Mobile: https://developer.android.com/design/ui/mobile (siehe die Guides in diesem Bereich)
PAUSE
Spätestens hier eine Pause einlegen.