Skip to Content
Folienvorschau
Dauer
10 Minuten
Ziel
Einordnen, was KMP darüber hinaus kann

Themen

  • Plattformspezifischer Code mit expect und actual
  • Ressourcen
  • Bibliotheken für KMP
  • Übungen
Klicken für Tastaturnavigation · F für Vollbild
Präsentation starten · 10 Minuten ↗

Ausblick

expect und actual

Gemeinsamer Code deklariert, die Plattformen liefern die Umsetzung (Beispiel aus dem Wizard-Projekt, Tag kmp-00):

// commonMain expect fun getPlatform(): Platform // androidMain actual fun getPlatform(): Platform = AndroidPlatform() // iosMain actual fun getPlatform(): Platform = IOSPlatform()

Das Beispiel stammt aus dem Projekt, das der Wizard erzeugt (kmp-00). In der Wetter-App haben wir diese Dateien beim Übernehmen gelöscht. AndroidPlatform liest die Android-Version über Build.VERSION.SDK_INT, IOSPlatform die iOS-Version über UIDevice. In androidMain und iosMain stehen also die nativen APIs der jeweiligen Plattform zur Verfügung.

So ließe sich zum Beispiel Dynamic Color zurückholen: unter Android die Farben aus dem Hintergrundbild, unter iOS die festen Farben.

Ressourcen

Bilder, Icons und Texte liegen in shared/src/commonMain/composeResources/ und werden über die generierte Klasse Res angesprochen:

Image(painterResource(Res.drawable.compose_multiplatform), null)

Das ersetzt R.drawable… aus der Android-App. Auch dieses Beispiel stammt aus dem Projekt des Wizards; in der Wetter-App haben wir den Ordner beim Übernehmen gelöscht.

Bibliotheken

Vor dem Einbinden prüfen: Gibt es die Bibliothek für KMP?

  • Ktor, kotlinx.serialization, Navigation 3, ViewModel: ja (haben wir benutzt)
  • Room und DataStore: ja
  • Retrofit, Gson: nein, nur Android bzw. JVM

Eine Sammlung von Bibliotheken für KMP: kmp-awesome . Für die Wetter-App war Ktor statt Retrofit deshalb die richtige Wahl.

Übungen

  • Koordinaten in der Städteliste auf zwei Nachkommastellen runden
  • Dynamic Color unter Android mit expect/actual
  • Zurück-Pfeil in der TopAppBar als Ressource in composeResources
  • Stadtsuche, Vorhersage, Favoriten aus dem Android-Teil umsetzen

Hinweise:

  • Runden: String.format gibt es in Common Kotlin nicht. Eine Möglichkeit: (value * 100).roundToInt() / 100.0 (mit 100.0, sonst rechnet Kotlin mit ganzen Zahlen). Aus 47,999 wird dann aber „48.0“ statt „48.00“; für genau zwei Nachkommastellen muss man auffüllen.
  • Dynamic Color: In commonMain z. B. @Composable expect fun dynamicColorScheme(darkTheme: Boolean): ColorScheme? deklarieren. In androidMain wie im ursprünglichen Theme mit LocalContext und der Prüfung auf Android 12 umsetzen, in iosMain null zurückgeben. Das Theme nimmt dann dynamicColorScheme(darkTheme) ?: if (darkTheme) DarkColorScheme else LightColorScheme.
  • Zurück-Pfeil: Den Ordner shared/src/commonMain/composeResources/drawable/ anlegen (beim Übernehmen gelöscht) und die Vector-XML von fonts.google.com/icons  hineinlegen. Verweise auf Android-Ressourcen funktionieren hier nicht: android:tint entfernen und android:fillColor auf einen Farbwert wie #000000 setzen (Anleitung ). Nach einem Build steht das Icon bereit, z. B. für arrow_back.xml: painterResource(Res.drawable.arrow_back) in einem IconButton, wie im Android-Teil. Die Imports unterscheiden sich von Android: org.jetbrains.compose.resources.painterResource sowie Res und arrow_back aus weatherkmptif24.shared.generated.resources.
  • Stadtsuche: Die Referenzlösung aus schritt-11 lässt sich wie in diesem Kapitel übernehmen. Ktor und die Geocoding-API funktionieren in KMP genauso. Anzupassen sind dieselben Stellen wie oben: viewModel { CityListViewModel() } statt viewModel() und kein "%.2f".format(…) in der Städteliste.
  • Favoriten: Room und DataStore funktionieren auch in KMP, siehe Room für KMP  und das Codelab Room nach KMP migrieren . Ein Beispiel mit Room unter Android und iOS ist die Todo-App aus dem Vorjahr: TodosKMP2025 .

Weiterführendes Material