Flutter Cheatsheet
Flutter - Build Apps für alle Screen
Flutter ist das UI-Toolkit von Google, um schöne, native zusammengestellte Anwendungen für mobile, Web und Desktop von einer einzigen Codebasis zu erstellen. Es ist bekannt für seine expressive UI, schnelle Entwicklung Zyklus und native Leistung. < p>
Inhaltsverzeichnis
- [Installation](LINK_0 -%20(LINK_0)
- Core Concepts
- (__LINK_0___)
- (__LINK_0___)
- [Navigation](LINK_0 -%20[State%20Management](_LINK_0 -%20[Networking](_LINK_0 -%20[Beständigkeit](LINK_0 -%20[Animations](_LINK_0 -%20[Platform%20Integration](_LINK_0 -%20Test
- [Debugging](_LINK_0__ -%20[Bestellung](_LINK_0___ -%20Beste%20Praktiken
- (__LINK_0___)
Installation
Flutter SDK
# Download Flutter SDK from https://flutter.dev/docs/get-started/install
# Extract the zip file
# Add Flutter to your path (for the current terminal session)
export PATH="$PATH:`pwd`/flutter/bin"
# Add Flutter to your path permanently (macOS/Linux)
echo 'export PATH="$PATH:[PATH_TO_FLUTTER_GIT_DIRECTORY]/flutter/bin"' >> ~/.zshrc
source ~/.zshrc
# Add Flutter to your path permanently (Windows)
# Update your system's environment variables
```_
### Aufbau der Plattform
#### Android Setup
```bash
# Install Android Studio
# Download from https://developer.android.com/studio
# Set up Android emulator
# Open Android Studio > AVD Manager > Create Virtual Device
# Accept Android licenses
flutter doctor --android-licenses
```_
#### iOS Setup (nur macOS)
```bash
# Install Xcode
# Download from Mac App Store
# Install CocoaPods
sudo gem install cocoapods
# Set up iOS simulator
open -a Simulator
```_
### Flutter Doktor
```bash
# Check your environment and see a report of the status of your Flutter installation
flutter doctor
# Verbose output
flutter doctor -v
```_
## Erste Schritte
### Neues Projekt erstellen
```bash
# Create a new Flutter project
flutter create my_app
# Navigate to the project directory
cd my_app
# Create a project with a specific organization
flutter create --org com.example my_app
# Create a project with a specific template
flutter create -t module my_module
```_
### Die App starten
```bash
# Run the app on an available device
flutter run
# Run on a specific device
flutter run -d chrome
flutter run -d 'iPhone 12'
# Run in release mode
flutter run --release
# Run with hot reload
# Press 'r' in the terminal
# Run with hot restart
# Press 'R' in the terminal
```_
### Projektstruktur
my_app/ ├── android/ # Android-specific code ├── ios/ # iOS-specific code ├── lib/ # Main Dart code │ ├── main.dart # App entry point │ ├── screens/ # Screen widgets │ ├── widgets/ # Reusable widgets │ ├── models/ # Data models │ ├── services/ # API services │ └── utils/ # Utility functions ├── test/ # Test files ├── pubspec.yaml # Project dependencies and metadata └── README.md # Project documentation ```_
Kernkonzepte
Dart Language Basics
```dart // Variables var name = 'Flutter'; String language = 'Dart'; int year = 2017; double version = 2.12; bool isAwesome = true;
// Functions int add(int a, int b) { return a + b; }
// Arrow syntax int multiply(int a, int b) => a * b;
// Classes class Person { String name; int age;
Person(this.name, this.age);
void sayHello() { print('Hello, my name is $name and I am $age years old.'); } }
// Asynchronous programming
Future
void main() async { var person = Person('John Doe', 30); person.sayHello();
print('Fetching data...'); var data = await fetchData(); print(data); } ```_
Alles ist ein Widget
```dart import 'package:flutter/material.dart';
void main() { runApp( MaterialApp( home: Scaffold( appBar: AppBar( title: Text('My First Flutter App'), ), body: Center( child: Text('Hello, Flutter!'), ), ), ), ); } ```_
Erstellen von Kontexten
```dart // BuildContext provides information about the location of a widget in the widget tree. // It is used to access theme data, navigation, and other inherited widgets.
class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( onPressed: () { Scaffold.of(context).showSnackBar( SnackBar(content: Text('Button pressed')), ); }, child: Text('Press Me'), ); } } ```_
Stateless vs. Staatliche Widgets
```dart // StatelessWidget: A widget that does not require mutable state. class MyStatelessWidget extends StatelessWidget { final String title;
MyStatelessWidget({required this.title});
@override Widget build(BuildContext context) { return Text(title); } }
// StatefulWidget: A widget that has mutable state. class MyStatefulWidget extends StatefulWidget { @override _MyStatefulWidgetState createState() => _MyStatefulWidgetState(); }
class _MyStatefulWidgetState extends State
void _incrementCounter() { setState(() { _counter++; }); }
@override Widget build(BuildContext context) { return Column( children: [ Text('Counter: $counter'), RaisedButton( onPressed: _incrementCounter, child: Text('Increment'), ), ], ); } } ```
Widgets
Basic Widgets
```dart import 'package:flutter/material.dart';
class BasicWidgets extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Basic Widgets')), body: SingleChildScrollView( padding: EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Text Text('This is a Text widget', style: TextStyle(fontSize: 18)), SizedBox(height: 20),
// Icon
Icon(Icons.favorite, color: Colors.red, size: 30),
SizedBox(height: 20),
// Image
Image.network('https://flutter.dev/images/flutter-logo-sharing.png'),
SizedBox(height: 20),
// Asset Image
Image.asset('assets/images/logo.png'),
SizedBox(height: 20),
// Button
RaisedButton(
onPressed: () {},
child: Text('RaisedButton'),
),
SizedBox(height: 10),
FlatButton(
onPressed: () {},
child: Text('FlatButton'),
),
SizedBox(height: 10),
IconButton(
onPressed: () {},
icon: Icon(Icons.thumb_up),
),
SizedBox(height: 20),
// TextField
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
border: OutlineInputBorder(),
),
),
SizedBox(height: 20),
// Checkbox
CheckboxListTile(
title: Text('Accept terms and conditions'),
value: true,
onChanged: (value) {},
),
SizedBox(height: 20),
// Radio
RadioListTile(
title: Text('Option 1'),
value: 1,
groupValue: 1,
onChanged: (value) {},
),
SizedBox(height: 20),
// Switch
SwitchListTile(
title: Text('Enable notifications'),
value: true,
onChanged: (value) {},
),
SizedBox(height: 20),
// Slider
Slider(
value: 0.5,
onChanged: (value) {},
),
SizedBox(height: 20),
// Progress Indicator
CircularProgressIndicator(),
SizedBox(height: 10),
LinearProgressIndicator(),
],
),
),
);
} } ```_
Materialkomponenten
```dart import 'package:flutter/material.dart';
class MaterialComponents extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Material Components')), drawer: Drawer( child: ListView( children: [ DrawerHeader(child: Text('Drawer Header')), ListTile(title: Text('Item 1')), ListTile(title: Text('Item 2')), ], ), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Card Card( child: Padding( padding: EdgeInsets.all(16.0), child: Text('This is a Card'), ), ), SizedBox(height: 20),
// Chip
Chip(
avatar: CircleAvatar(child: Text('A')),
label: Text('Chip'),
),
SizedBox(height: 20),
// DataTable
DataTable(
columns: [
DataColumn(label: Text('ID')),
DataColumn(label: Text('Name')),
],
rows: [
DataRow(cells: [DataCell(Text('1')), DataCell(Text('John'))]),
DataRow(cells: [DataCell(Text('2')), DataCell(Text('Jane'))]),
],
),
SizedBox(height: 20),
// SnackBar
RaisedButton(
onPressed: () {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('This is a SnackBar')),
);
},
child: Text('Show SnackBar'),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
),
);
} } ```_
Layouts
Single-Child Layout Widgets
```dart import 'package:flutter/material.dart';
class SingleChildLayouts extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Single-Child Layouts')), body: Column( children: [ // Container Container( color: Colors.blue, padding: EdgeInsets.all(16.0), margin: EdgeInsets.all(16.0), child: Text('Container'), ),
// Center
Center(
child: Text('Center'),
),
// Padding
Padding(
padding: EdgeInsets.all(16.0),
child: Text('Padding'),
),
// Align
Align(
alignment: Alignment.bottomRight,
child: Text('Align'),
),
// SizedBox
SizedBox(
width: 200,
height: 100,
child: Card(child: Center(child: Text('SizedBox'))),
),
// AspectRatio
AspectRatio(
aspectRatio: 16 / 9,
child: Container(color: Colors.green),
),
// ConstrainedBox
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200, maxHeight: 100),
child: Container(color: Colors.red),
),
],
),
);
} } ```_
Multi-Child Layout Widgets
```dart import 'package:flutter/material.dart';
class MultiChildLayouts extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Multi-Child Layouts')), body: Column( children: [ // Row Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [Text('Row 1'), Text('Row 2'), Text('Row 3')], ),
// Column
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text('Column 1'), Text('Column 2'), Text('Column 3')],
),
// Stack
Stack(
children: [
Container(width: 100, height: 100, color: Colors.red),
Container(width: 80, height: 80, color: Colors.green),
Container(width: 60, height: 60, color: Colors.blue),
],
),
// ListView
Expanded(
child: ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
),
),
// GridView
Expanded(
child: GridView.count(
crossAxisCount: 2,
children: List.generate(4, (index) => Center(child: Text('Item $index'))),
),
),
],
),
);
} } ```_
Navigation
Navigator 1.0 (Imperativ)
```dart // Navigate to a new screen Navigator.push( context, MaterialPageRoute(builder: (context) => DetailsScreen()), );
// Navigate back Navigator.pop(context);
// Navigate with data Navigator.push( context, MaterialPageRoute( builder: (context) => DetailsScreen(item: item), ), );
// Receive data from a screen final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => SelectionScreen()), );
// Send data back Navigator.pop(context, 'Yes'); ```_
Navigator 2.0 (Erklärung)
```dart // pubspec.yaml dependencies: flutter: sdk: flutter go_router: ^3.0.0
// main.dart import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp.router( routeInformationParser: _router.routeInformationParser, routerDelegate: _router.routerDelegate, ); }
final _router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(), ), GoRoute( path: '/details/:id', builder: (context, state) => DetailsScreen(id: state.params['id']!), ), ], ); }
// Navigate with go_router context.go('/details/123'); context.push('/details/456'); ```_
Staatliche Verwaltung
Anbieter
```dart // pubspec.yaml dependencies: provider: ^6.0.0
// main.dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart';
void main() { runApp( ChangeNotifierProvider( create: (context) => Counter(), child: MyApp(), ), ); }
class Counter with ChangeNotifier { int _count = 0; int get count => _count;
void increment() { _count++; notifyListeners(); } }
// Usage in a widget
class CounterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Provider Example')),
body: Center(
child: Text('Count: ${context.watch
BLoC (Business Logic Component)
```dart // pubspec.yaml dependencies: flutter_bloc: ^8.0.0
// counter_event.dart abstract class CounterEvent {} class Increment extends CounterEvent {}
// counter_bloc.dart import 'package:bloc/bloc.dart'; import 'counter_event.dart';
class CounterBloc extends Bloc
// main.dart import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
void main() { runApp( BlocProvider( create: (context) => CounterBloc(), child: MyApp(), ), ); }
// Usage in a widget
class CounterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('BLoC Example')),
body: Center(
child: BlocBuilder
Riverpod
```dart // pubspec.yaml dependencies: flutter_riverpod: ^1.0.0
// main.dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateProvider((ref) => 0);
void main() { runApp(ProviderScope(child: MyApp())); }
// Usage in a widget class CounterScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text('Riverpod Example')),
body: Center(
child: Text('Count: $count'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.state).state++,
child: Icon(Icons.add),
),
);
} } ```_
Vernetzung
http-Paket
```dart // pubspec.yaml dependencies: http: ^0.13.0
// services/api_service.dart import 'package:http/http.dart' as http; import 'dart:convert';
class ApiService { Future
Dio Paket
```dart // pubspec.yaml dependencies: dio: ^4.0.0
// services/api_service.dart import 'package:dio/dio.dart';
class ApiService { final dio = Dio();
Future
Persistenz
Shared_Präferenzen
```dart // pubspec.yaml dependencies: shared_preferences: ^2.0.0
// utils/storage.dart import 'package:shared_preferences/shared_preferences.dart';
class Storage {
Future
Future
Sqflite
```dart // pubspec.yaml dependencies: sqflite: ^2.0.0 path: ^1.8.0
// services/database_service.dart import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart';
class DatabaseService { late Database _database;
Future
Future
Future>> getUsers() async {
return await database.query('users');
}
}
```
Animationen
Implizite Animationen
```dart class ImplicitAnimation extends StatefulWidget { @override _ImplicitAnimationState createState() => _ImplicitAnimationState(); }
class _ImplicitAnimationState extends State
@override Widget build(BuildContext context) { return GestureDetector( onTap: () => setState(() => isBig = !_isBig), child: AnimatedContainer( duration: Duration(seconds: 1), width: _isBig ? 200 : 100, height: _isBig ? 200 : 100, color: _isBig ? Colors.blue : Colors.red, ), ); } } ```
Explicit Animationen
```dart class ExplicitAnimation extends StatefulWidget { @override _ExplicitAnimationState createState() => _ExplicitAnimationState(); }
class _ExplicitAnimationState extends State
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
_animation = Tween
@override void dispose() { _controller.dispose(); super.dispose(); }
@override Widget build(BuildContext context) { return Container( width: animation.value, height: _animation.value, color: Colors.green, ); } } ```
Integration von Plattformen
MethodChannel
```dart // Dart side import 'package:flutter/services.dart';
const platform = MethodChannel('com.example.myapp/channel');
Future
// Android side (MainActivity.java) import io.flutter.embedding.android.FlutterActivity; import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends FlutterActivity { private static final String CHANNEL = "com.example.myapp/channel";
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler( (call, result) -> { if (call.method.equals("getBatteryLevel")) { // ... get battery level result.success(batteryLevel); } } ); } } ```_
Prüfung
Einheitsprüfung
```dart // test/counter_test.dart import 'package:test/test.dart'; import 'package:my_app/counter.dart';
void main() { test('Counter value should be incremented', () { final counter = Counter(); counter.increment(); expect(counter.value, 1); }); } ```_
Widget Testing
```dart // test/widget_test.dart import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:my_app/main.dart';
void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { await tester.pumpWidget(MyApp());
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
}); } ```_
Integrationstests
```dart // test_driver/app_test.dart import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart';
void main() { group('Counter App', () { FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() async {
if (driver != null) {
driver.close();
}
});
test('increments the counter', () async {
final counterTextFinder = find.byValueKey('counter');
final buttonFinder = find.byValueKey('increment');
expect(await driver.getText(counterTextFinder), '0');
await driver.tap(buttonFinder);
expect(await driver.getText(counterTextFinder), '1');
});
}); } ```_
Debugging
DevTools
```bash
Open DevTools from the terminal
flutter pub global activate devtools flutter pub global run devtools
Or from VS Code / Android Studio
```_
Protokoll
```dart import 'dart:developer' as developer;
void myFunction() { developer.log('This is a log message', name: 'my.app.category'); } ```_
Bereitstellung
Android
```bash
Build an APK
flutter build apk
Build an App Bundle
flutter build appbundle ```_
iOS
```bash
Build an IPA
flutter build ipa ```_
Web
```bash
Build for web
flutter build web ```_
Best Practices
- *Follow Effektive Dart Leitlinien: Schreiben Sie sauber, pflegeleicht Dart-Code.
- *Organisieren Sie Ihre Projektstruktur: Halten Sie Ihren Code organisiert und einfach zu navigieren.
- ** Verwenden Sie eine staatliche Managementlösung*: Wählen Sie eine State Management Lösung, die der Komplexität Ihrer App entspricht.
- *Writtests: Schreibeinheit, Widget und Integrationstests, um sicherzustellen, dass Ihre App richtig funktioniert.
- Optimieren Sie die Leistung: Verwenden Sie DevTools, um Leistungsengpässe zu identifizieren und zu beheben.
- *Handle-Fehler anmutig: Verwenden Sie Try-Catch Blöcke und Fehler Widgets, um Fehler zu handhaben.
Fehlerbehebung
Gemeinsame Themen
- *Platformspezifische Probleme: Überprüfen Sie Ihren Plattformaufbau (Android Studio, Xcode).
- ** Abhängigkeitskonflikte*: Führen Sie
flutter pub deps
aus, um nach Abhängigkeitskonflikten zu suchen. - Baufehler: Führen Sie
flutter clean
und dannflutter pub get
_ aus, um Ihre Build-Dateien zu reinigen.
--
Zusammenfassung
Flutter ist ein leistungsstarkes und flexibles UI-Toolkit zum Aufbau hochwertiger, plattformübergreifender Anwendungen. Die wichtigsten Funktionen sind:
- Fast Development: Heißes Nachladen ermöglicht es Ihnen, Änderungen sofort zu sehen.
- *Expressive UI: Erstellen Sie schöne und benutzerdefinierte UIs mit einem reichen Satz von Widgets.
- Native Performance: Flutter-Apps werden auf nativen Code kompiliert und bieten hervorragende Leistungen.
- *Single Codebase: Einmal schreiben, auf Handy, Web und Desktop laufen.
- *Growing Community: Eine große und aktive Gemeinschaft bietet Unterstützung und ein reiches Ökosystem an Paketen.
Flutter ist eine ausgezeichnete Wahl für Entwickler, die schöne, leistungsstarke Anwendungen für mehrere Plattformen mit einer einzigen Codebasis erstellen möchten.
<= <= <= <================================================================================= Funktion copyToClipboard() {\cHFFFF} const commands = document.querySelectorAll('code'); alle Befehle = ''; Befehle. Für jede(cmd) => alle Befehle += cmd.textContent + '\n'); navigator.clipboard.writeText (allCommands); Alarm ('Alle Befehle, die in die Zwischenablage kopiert werden!'); }
Funktion generierenPDF() { Fenster.print(); }