Flutter in Kürze
Flutter zeichnet Oberflächen selbst (eigene Rendering-Engine) und läuft auf Android, iOS, Web, Windows, macOS und Linux. Alles ist ein Widget: Text, Button, Layout, sogar Abstände. Widgets werden verschachtelt und neu gebaut, wenn sich der Zustand ändert.
flutter create meine_app
cd meine_app
flutter run # startet auf Gerät/Emulator/Browser
flutter test
flutter build apk # Android
flutter build webEin Zähler als Flutter-App
import 'package:flutter/material.dart';
void main() => runApp(const MeineApp());
class MeineApp extends StatelessWidget {
const MeineApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Zähler',
theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true),
home: const ZaehlerSeite(),
);
}
}
class ZaehlerSeite extends StatefulWidget {
const ZaehlerSeite({super.key});
@override
State<ZaehlerSeite> createState() => _ZaehlerSeiteState();
}
class _ZaehlerSeiteState extends State<ZaehlerSeite> {
int _anzahl = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Zähler')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Du hast so oft gedrückt:'),
Text('$_anzahl', style: Theme.of(context).textTheme.displayLarge),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => _anzahl++),
child: const Icon(Icons.add),
),
);
}
}- StatelessWidget: ohne eigenen Zustand
- StatefulWidget +
setState: lokaler Zustand; Flutter baut nur die betroffenen Widgets neu - Layout:
Row,Column,Stack,Expanded,Padding,ListView,GridView - Navigation:
Navigator,go_router - Zustandsverwaltung:
Provider,Riverpod,Bloc - Hot Reload: Code speichern, die App aktualisiert sich ohne Neustart
Pakete (pub.dev)
dart pub add http
dart pub add intl| Gebiet | Pakete |
|---|---|
| Netzwerk | http, dio |
| JSON | json_serializable, freezed |
| Zustand | provider, riverpod, flutter_bloc |
| Speicher | shared_preferences, sqflite, drift, hive |
| Backend | firebase_core, supabase_flutter |
| Server | shelf, dart_frog, serverpod |
| Tests | test, flutter_test, mocktail |
Die Datei pubspec.yaml beschreibt Projekt und Abhängigkeiten:
name: meine_app
environment:
sdk: ^3.5.0
dependencies:
http: ^1.2.0
intl: ^0.19.0
dev_dependencies:
test: ^1.25.0
lints: ^4.0.0Daten aus dem Netz
import 'dart:convert';
import 'package:http/http.dart' as http;
class Beitrag {
final int id;
final String titel;
Beitrag({required this.id, required this.titel});
factory Beitrag.fromJson(Map<String, dynamic> j) => Beitrag(id: j['id'], titel: j['title']);
}
Future<List<Beitrag>> ladeBeitraege() async {
final antwort = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (antwort.statusCode != 200) throw Exception('HTTP ${antwort.statusCode}');
final liste = jsonDecode(antwort.body) as List;
return liste.map((e) => Beitrag.fromJson(e)).toList();
}In Flutter zeigt ein FutureBuilder Ladezustand, Fehler und Daten an.
Tests
import 'package:test/test.dart';
int addiere(int a, int b) => a + b;
void main() {
group('addiere', () {
test('positive Zahlen', () => expect(addiere(2, 3), 5));
test('negative Zahlen', () => expect(addiere(-2, -3), -5));
test('wirft bei Fehler', () => expect(() => int.parse('x'), throwsFormatException));
});
}Starten mit dart test.
Merke
- Flutter: ein Code für alle Plattformen, alles ist ein Widget, Hot Reload
StatelessWidget/StatefulWidget,setState, Layout-Widgets (Row,Column,ListView)- Pakete von pub.dev über
dart pub add, Projektdateipubspec.yaml - Netzwerk mit
http, JSON mitdart:convert - Dart auch für Server und Kommandozeile
Aufgabe
Skizziere die Widgetstruktur einer To-do-App (Liste, Eingabefeld, Button).