Eine Liste von Städten, nach Antippen das aktuelle Wetter der Stadt.
schritt-05Der Kotlin-Code ist nach Aufgaben in Pakete aufgeteilt.
app/src/main/java/com/example/weatherandroidtif24/
├── MainActivity.kt
├── ui/ Screens und Composables, ViewModels
│ └── theme/ Farben, Schriften, Theme (aus der Vorlage)
├── model/ Datenmodell: City, CurrentWeather
└── data/ Datenquellen: Fake-Daten, Repositorys
└── api/ HTTP-Client und DTOs (ab Schritt 9)Ein Composable ist eine Kotlin-Funktion, die beschreibt, wie ein Teil der Oberfläche aussieht.
@Composable
fun WeatherScreen(modifier: Modifier = Modifier) {
Text(text = "Lörrach", modifier = modifier)
Text(text = "14 °C", modifier = modifier)
}Mit @Preview zeigt Android Studio ein Composable direkt im Editor an, ohne Emulator.
@Preview(showBackground = true)
@Composable
fun WeatherScreenPreview() {
WeatherScreen()
}Composables werden mit Layout-Composables angeordnet.
Column: untereinanderRow: nebeneinanderBox: übereinander, z. B. Inhalt auf einem HintergrundSpacer: Abstand bzw. freier PlatzDie Verschachtelung im Code entspricht der Verschachtelung auf dem Bildschirm.
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Lörrach", fontSize = 28.sp)
Text(text = "⛅", fontSize = 72.sp)
Text(text = "14 °C", fontSize = 48.sp)
Spacer(modifier = Modifier.height(16.dp))
Row(modifier = Modifier.fillMaxWidth()) {
Text(text = "Wind: 8 km/h")
Spacer(modifier = Modifier.weight(1f))
Text(text = "Teilweise bewölkt")
}
}Modifier verändern Größe, Abstand, Hintergrund und Verhalten eines Composables. Sie werden durch aufeinanderfolgende Funktionsaufrufe verkettet.
Box(
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
.background(Color(0xFFBBDEFB), RoundedCornerShape(24.dp))
.padding(24.dp),
contentAlignment = Alignment.Center,
) { /* Column von oben */ }Statt fester Texte bekommen Composables nun Daten als Parameter.
data class City(
val name: String,
val latitude: Double,
val longitude: Double,
)
data class CurrentWeather(
val temperature: Double,
val windSpeed: Double,
val condition: WeatherCondition,
)Composables sollten Daten als Parameter erhalten und sie nicht eigenständig holen.
@Composable
fun CurrentWeatherCard(
city: City,
weather: CurrentWeather,
modifier: Modifier = Modifier,
) {
// ...
Text(text = city.name)
Text(text = weather.condition.emoji())
Text(text = "${weather.temperature.roundToInt()} °C")
}Compose bringt die Komponenten von Material Design 3 mit, dem Designsystem von Google. Scaffold ist das Grundgerüst eines Screens, z. B. mit einer TopAppBar.
Scaffold(
topBar = { TopAppBar(title = { Text(text = city.name) }) },
) { innerPadding ->
CurrentWeatherCard(
city = city,
weather = weather,
modifier = Modifier.padding(innerPadding),
)
}highlighted, der die Karte mit einem Rahmen hervorhebt