Appearance
Kapitel 18: Interviewfragen
18.1 Grundlegende Konzeptfragen
Frage 1: Was ist Flutter?
Antwort: Flutter ist ein von Google entwickeltes cross-platform UI Framework, mit dem Entwickler mit einer einzigen Codebasis native Apps für iOS, Android, Web und Desktop erstellen können.
Wichtigste Merkmale:
- ✅ Programmiersprache: Dart (offizielle Sprache von Flutter)
- ✅ Ein Codebase: Läuft auf iOS, Android, Web, Windows, Mac, Linux
- ✅ Native Performance: Kompiliert zu nativen ARM-Code
- ✅ Widget-System: Alles ist ein Widget (Komponente)
Frage 2: Was sind die Kernvorteile von Flutter?
Antwort:
| Vorteil | Beschreibung |
|---|---|
| Cross-Platform Konsistenz | Gleiches Aussehen und Verhalten auf allen Plattformen |
| Hohe Performance | Direct Rendering, keine Bridge wie bei React Native |
| Hot Reload | Sofortige Vorschau von Änderungen ohne App-Neustart |
| Hohe Entwicklungseffizienz | Ein Codebase für alle Plattformen |
| Tiefe Dart-Integration | Nahtlose Zusammenarbeit mit Dart |
Frage 3: Was ist der Unterschied zwischen StatelessWidget und StatefulWidget?
Antwort:
| Merkmal | StatelessWidget | StatefulWidget |
|---|---|---|
| Zustand | Kein Zustand | Hat Zustand (State) |
| Veränderlichkeit | Unveränderlich | Veränderlich |
| Performance | Besser (weniger Overhead) | Schlechter (Rebuilding) |
| Komplexität | Einfacher | Komplexer |
| Anwendung | Statische Inhalte | Interaktive Inhalte |
Entscheidungshilfe:
Brauche ich interaktive Elemente?
├── NEIN → StatelessWidget
└── JA → StatefulWidget
├── Einfache Interaktion → StatefulWidget
└── Komplexe Zustandsverwaltung → Provider/Bloc (später)Frage 4: Was ist Hot Reload und wie funktioniert es?
Antwort:Hot Reload:
- ✅ Aktualisiert UI sofort
- ✅ Behält App-Zustand bei (Variablen, Daten)
- ✅ Funktioniert nur im Debug-Modus
- ✅ Sehr schnell (Millisekunden)
Hot Restart:
- ✅ Startet App neu
- ✅ Setzt App-Zustand zurück
- ✅ Etwas langsamer als Hot Reload
Full Restart:
- ✅ Stoppt und startet App komplett neu
- ✅ Erforderlich bei Änderungen an nativen Dateien
18.2 Kernfunktionalitätsfragen
Frage 5: Was sind die wichtigsten Layout-Widgets in Flutter?
Antwort:
1. Row (Horizontales Layout)
dart
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(Icons.home),
Text('Startseite'),
ElevatedButton(onPressed: () {}, child: Text('Go')),
],
)2. Column (Vertikales Layout)
dart
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('Zeile 1'),
Text('Zeile 2'),
ElevatedButton(onPressed: () {}, child: Text('Button')),
],
)3. Stack (Stapel-Layout)
dart
Stack(
children: <Widget>[
Container(width: 200, height: 200, color: Colors.red),
Positioned(
top: 10,
left: 10,
child: Icon(Icons.home, size: 30),
),
],
)Frage 6: Was ist setState() und wann verwendet man es?
Antwort:setState() ist die einfachste Form der Zustandsverwaltung in Flutter.
Verwendung:
dart
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _zaehler = 0;
void _erhoehen() {
setState(() { // WICHTIG: setState() aktualisiert UI
_zaehler++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$_zaehler', style: const TextStyle(fontSize: 48)),
ElevatedButton(
onPressed: _erhoehen,
child: const Text('Erhöhen'),
),
],
),
),
);
}
}Wann setState() verwenden?
- ✅ Einfache Zustände (lokaler Zustand)
- ✅ Wenige Widgets betroffen
- ✅ Keine komplexe Zustandsverwaltung notwendig
Frage 7: Was ist Provider und wann verwendet man es?
Antwort:Provider ist eine offiziell empfohlene Lösung für Zustandsverwaltung in Flutter.
Vorteile:
- ✅ Einfach zu verwenden
- ✅ Gute Leistung
- ✅ Gute Dokumentation
Verwendung (3 Schritte):
Schritt 1: Zustands-Klasse definieren (ChangeNotifier)
dart
class CounterProvider extends ChangeNotifier {
int _zaehler = 0;
int get zaehler => _zaehler;
void erhoehen() {
_zaehler++;
notifyListeners(); // WICHTIG: Benachrichtigt alle Zuhörer!
}
}Schritt 2: Zustand bereitstellen (Provider)
dart
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CounterProvider(),
child: const MyApp(),
),
);
}Schritt 3: Zustand verbrauchen (Consumer / Provider.of)
dart
class CounterPage extends StatelessWidget {
const CounterPage({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Consumer<CounterProvider>(
builder: (context, provider, child) {
return Text(
'${provider.zaehler}',
style: const TextStyle(fontSize: 48),
);
},
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Provider.of<CounterProvider>(context, listen: false).erhoehen();
},
child: const Text('Erhöhen'),
),
],
),
);
}
}18.3 Praxisszenario-Fragen
Frage 8: Wie erstellt man eine Login-Seite mit Formularvalidierung?
Antwort:
Vollständiger Code:
dart
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
void _login() {
if (_formKey.currentState!.validate()) {
// Formular ist gültig
final username = _usernameController.text;
final password = _passwordController.text;
if (username == 'admin' && password == '123456') {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Login erfolgreich!')),
);
// Hier zur nächsten Seite navigieren
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Login fehlgeschlagen!'),
backgroundColor: Colors.red,
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Login')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: _usernameController,
decoration: const InputDecoration(
labelText: 'Benutzername',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte Benutzernamen eingeben';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Passwort',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte Passwort eingeben';
}
},
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _login,
child: const Text('Login'),
),
],
),
),
),
);
}
@override
void dispose() {
_usernameController.dispose();
_passwordController.dispose();
super.dispose();
}
}Frage 9: Wie ruft man Daten von einer API ab und zeigt sie in einer Liste an?
Antwort:
Vollständiger Code:
dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
// Modellklasse
class Post {
final int id;
final String title;
final String body;
Post({required this.id, required this.title, required this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
class PostsPage extends StatefulWidget {
const PostsPage({super.key});
@override
State<PostsPage> createState() => _PostsPageState();
}
class _PostsPageState extends State<PostsPage> {
List<Post> _posts = [];
bool _isLoading = false;
String _errorMessage = '';
@override
void initState() {
super.initState();
_ladePosts();
}
Future<void> _ladePosts() async {
setState(() {
_isLoading = true;
_errorMessage = '';
});
try {
final dio = Dio();
final response = await dio.get('https://jsonplaceholder.typicode.com/posts?_limit=10');
final List<dynamic> data = response.data;
final posts = data.map((json) => Post.fromJson(json)).toList();
setState(() {
_posts = posts;
_isLoading = false;
});
} catch (e) {
setState(() {
_errorMessage = 'Fehler beim Laden: $e';
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Posts')),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
onPressed: _ladePosts,
child: const Icon(Icons.refresh),
),
);
}
Widget _buildBody() {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (_errorMessage.isNotEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(Icons.error, size: 64, color: Colors.red),
const SizedBox(height: 16),
Text(_errorMessage, textAlign: TextAlign.center),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _ladePosts,
child: const Text('Erneut versuchen'),
),
],
),
);
}
return ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return Card(
margin: const EdgeInsets.all(8),
child: ListTile(
title: Text(
post.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
post.body,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
);
},
);
}
}18.4 Häufige Fehlerpunkte-Fragen
Frage 10: Was sind häufige Fehler bei der Zustandsverwaltung?
Antwort:
Fehler 1: setState() vergessen
dart
// FALSCH
void _erhoehen() {
_zaehler++; // UI wird NICHT aktualisiert!
}
// RICHTIG
void _erhoehen() {
setState(() {
_zaehler++; // UI wird aktualisiert!
});
}Fehler 2: notifyListeners() vergessen (bei Provider)
dart
// FALSCH
void erhoehen() {
_zaehler++;
// notifyListeners() vergessen! UI wird nicht aktualisiert.
}
// RICHTIG
void erhoehen() {
_zaehler++;
notifyListeners(); // UI wird aktualisiert!
}Fehler 3: Zustand kann nicht einfach zwischen nicht-verwandten Widgets geteilt werden
- Lösung:
Provideroder andere Zustandsverwaltungs-Lösung verwenden.
Frage 11: Was sind häufige Fehler bei Netzwerkanfragen?
Antwort:
Fehler 1: Internet-Berechtigung fehlt (Android)
- Lösung:
android/app/src/main/AndroidManifest.xmlbearbeiten:
xml
<manifest xmlns:android="...">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Weitere Konfiguration -->
</manifest>Fehler 2: await vergessen
dart
// FALSCH
void ladeDaten() {
final response = dio.get('https://example.com'); // Future nicht awaited!
print(response.data); // Fehler: response ist kein Response-Objekt
}
// RICHTIG
Future<void> ladeDaten() async {
final response = await dio.get('https://example.com'); // await verwenden!
print(response.data);
}Fehler 3: Fehlerbehandlung vergessen
- Lösung:
try-catchverwenden.
18.5 Dart-Verbindungsfragen
Frage 12: Was ist die Beziehung zwischen Dart und Flutter?
Antwort:
- ✅ Dart ist die Programmiersprache von Flutter.
- ✅ Flutter verwendet Dart als Programmiersprache.
- ✅ Dart wurde von Google speziell für Flutter entwickelt.
- ✅ Flutter verwendet Dart's Widget-System, um UI-Elemente zu erstellen.
Frage 13: Wie wird Dart in Flutter verwendet?
Antwort:
1. Variablen & Datentypen
dart
// In Flutter verwenden Sie oft Widget-Typen
Widget meinWidget = Text('Hallo'); // Widget-Typ
const String titel = 'Meine App'; // Konstante (Compile-Zeit)
final int zaehler = 0; // Final (Laufzeit-Konstante)2. Funktionen & Arrow-Syntax
dart
// Normale Funktion
Widget buildButton() {
return ElevatedButton(
onPressed: () {},
child: Text('Klick mich'),
);
}
// Arrow Function (kurz)
Widget buildText() => Text('Kurz und knapp');
// Callback-Funktion (wichtig für Events!)
ElevatedButton(
onPressed: () {
print('Button geklickt!');
},
child: Text('Klick'),
)3. Asynchrone Programmierung (Future, async/await)
dart
// In Flutter sehr wichtig für Netzwerkrequests!
Future<String> ladeDaten() async {
// Simuliere Netzwerkrequest
await Future.delayed(Duration(seconds: 2));
return 'Daten geladen';
}
// Verwendung in Flutter
ElevatedButton(
onPressed: () async {
String ergebnis = await ladeDaten();
print(ergebnis);
},
child: Text('Daten laden'),
)18.6 Interview-Tipps
Tipp 1: Kernkonzepte schnell memorieren
Wichtigste Konzepte:
- Widget: Alles ist ein Widget.
- StatelessWidget vs. StatefulWidget: Unterschied verstehen.
- setState(): Zustand aktualisieren.
- Provider: Zustand verwalten.
- Hot Reload: Schnelle Entwicklung.
Tipp 2: Fragen beantworten
Vorgehensweise:
- Frage verstehen: Stellen Sie sicher, dass Sie die Frage verstanden haben.
- Antwort strukturieren: Unterteilen Sie die Antwort in klare Punkte.
- Beispiele geben: Verwenden Sie Code-Beispiele, um Ihre Antwort zu verdeutlichen.
- Ehrlich sein: Wenn Sie etwas nicht wissen, sagen Sie es ehrlich.
Tipp 3: Praktische Fähigkeiten demonstrieren
Wichtigste Fähigkeiten:
- Flutter-Projekt erstellen:
flutter create mein_projekt - Widget erstellen: StatelessWidget / StatefulWidget
- Layouts erstellen: Row, Column, Stack
- Netzwerkrequests: Dio verwenden
- Zustandsverwaltung: setState(), Provider
Zusammenfassung
In diesem Kapitel haben Sie:
- ✅ Grundlegende Konzeptfragen beantwortet
- ✅ Kernfunktionalitätsfragen beantwortet
- ✅ Praxisszenario-Fragen beantwortet
- ✅ Häufige Fehlerpunkte-Fragen beantwortet
- ✅ Dart-Verbindungsfragen beantwortet
- ✅ Interview-Tipps gelernt
Nächstes Kapitel: Wir werden Erweiterte Lernswege lernen.
Übungsaufgaben:
- Beantworten Sie die Fragen in diesem Kapitel ohne Nachschauen.
- Erstellen Sie ein einfaches Flutter-Projekt und erklären Sie den Code.
- Üben Sie die Erklärung von Flutter-Konzepten (Widget, setState, Provider).
Häufige Fehler:
- ❌ Konzepte nicht verstanden → Wiederholen Sie die vorherigen Kapitel!
- ❌ Praktische Fähigkeiten nicht demonstrieren können → Üben Sie!
- ❌ Fragen nicht strukturiert beantworten → Üben Sie!
