Flutter ist ein Open-Source-Framework von Google für Apps auf Android, iOS, Web und Desktop aus einer Codebasis. Programmiert wird in Dart.
Die Flutter-Dokumentation empfiehlt VS Code mit der Flutter-Extension.
weather_flutter_tif24Der Dart-Code liegt in lib/, nach Aufgaben in Ordner aufgeteilt.
lib/
├── main.dart
├── ui/ Screens und Widgets, ViewModels
├── model/ Datenmodell: City, CurrentWeather
└── data/ Datenquellen: Fake-Daten, Repositorys
└── api/ DTOs für die API (ab Schritt 9)
pubspec.yaml Name, Abhängigkeiten, Assets
android/ ios/ web/ Plattform-Projekte, selten angefasstIn Flutter ist alles ein Widget: Text, Abstände, Layouts, ganze Screens.
Hot Reload: Speichern genügt, die Änderung ist in unter einer Sekunde im laufenden Emulator.
pubspec.yaml oder nativem CodeWidgets werden mit Layout-Widgets angeordnet.
Column: untereinanderRow: nebeneinanderStack: übereinanderContainer: Hintergrund, Rahmen, Abstände um ein KindSizedBox: fester Abstand, Spacer: freier PlatzDie Verschachtelung im Code entspricht der Verschachtelung auf dem Bildschirm.
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Lörrach', style: TextStyle(fontSize: 28)),
Text('⛅', style: TextStyle(fontSize: 72)),
Text('14 °C', style: TextStyle(fontSize: 48)),
SizedBox(height: 16),
Row(children: [Text('Wind: 8 km/h'), Spacer(), Text('Teilweise bewölkt')]),
],
)Einen Modifier gibt es nicht. Abstände und Hintergrund sind Eigenschaften von Container oder eigene Widgets wie Padding.
Container(
width: double.infinity,
margin: const EdgeInsets.all(16), // außen
padding: const EdgeInsets.all(24), // innen
decoration: BoxDecoration(
color: const Color(0xFFBBDEFB),
borderRadius: BorderRadius.circular(24),
),
child: const Column(/* von oben */),
)Statt fester Texte bekommen Widgets nun Daten über den Konstruktor.
class City {
const City({
required this.name,
required this.latitude,
required this.longitude,
});
final String name;
final double latitude;
final double longitude;
}Widgets sollten Daten über den Konstruktor erhalten und sie nicht eigenständig holen.
class CurrentWeatherCard extends StatelessWidget {
const CurrentWeatherCard({super.key, required this.city, required this.weather});
final City city;
final CurrentWeather weather;
@override
Widget build(BuildContext context) {
// Container und Column wie bisher, die Texte jetzt aus den Daten:
// Text(city.name), Text(weather.condition.emoji), ...
}
}@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(city.name)),
body: SingleChildScrollView(
child: CurrentWeatherCard(city: city, weather: weather),
),
);
}