Entwickeln mit Weitsicht: Mit Flutter zum Gipfel der App-Entwicklung
Eine Einführung und ein Überblick über die App-Entwicklung mit Flutter von Mirko Zohren, IT Consultant Web & Mobile Solutions
Flutter hat sich in den letzten Jahren als eines der flexibelsten und leistungsfähigsten Frameworks für die App-Entwicklung etabliert [1]. Mit dem Versprechen, eine einzige Codebasis für mobile, Web- und Desktop-Anwendungen bereitzustellen, bietet Flutter Entwickelnden nicht nur beeindruckende Vielseitigkeit, sondern auch eine moderne und intuitive Umgebung, um Ideen effizient in die Realität umzusetzen.
Die Kombination aus:
- schnellem Entwicklungszyklus,
- leistungsstarker Rendering-Engine
- und einer breiten Palette an vorgefertigten Widgets
macht Flutter zu einem Werkzeug, das sowohl Einsteigerinnen und Einsteiger als auch erfahrene Developer begeistert. Dabei ist Flutter nicht nur ein technisches Framework, sondern auch eine Community von Gleichgesinnten, die den Austausch von Wissen und Ressourcen aktiv fördert. Wer sich für die Arbeit mit Flutter entscheidet, begibt sich auf eine spannende Exkursion, bei der Kreativität und Effizienz Hand in Hand gehen. Ziehen wir also die Wanderschuhe an und begeben uns auf die Reise zum Mount Flutter.
Seiteninhalt
Einstieg in die App-Entwicklung mit Flutter
Entwickeln mit Weitsicht: Angehende Developer stehen häufig vor der Herausforderung, die „richtige“ Wahl zu treffen. Es stehen Hürden im Weg, die Unerfahrene möglicherweise nicht direkt als solche erkennen. Diese können je nach Erfahrungsschatz der Proband auf verschiedenen Ebenen der Reise auftreten. Wenig erfahrene Developer können schnell und einfach in die Entwicklung mit Flutter und der zugrundeliegenden Programmiersprache Dart eingeführt werden.
Schon die einfache Installation, die Unterstützung durch diverse Entwicklungsumgebungen (IDE) und auch die gelungene Dokumentation, helfen beim Einstiegsprozess. Dank der typensicheren Syntax werden häufige Laufzeitfehler vermieden, während NullSafety ein solides und zuverlässiges Arbeiten mit Objekten gewährleistet. Die Hot Reload- und Hot Restart-Funktionen ermöglichen unmittelbares Feedback auf Codeänderungen und schaffen so ein schnelles, intuitives und motivationsförderndes Entwicklungserlebnis.
Auch die mittlerweile zahlreich angebotenen Tutorials zum Einstieg auf den gängigen Plattformen, oder die vorbildlich gepflegte Dokumentation auf docs.flutter.dev helfen beim Start.
Häufig können Ideen schnell und unkompliziert mithilfe von Erweiterungen von pub.dev umgesetzt werden. Diese Erweiterungen bilden Zugriff auf bestimmte Funktionen, die nicht von Dart bzw. Flutter selbst bereitgestellt werden. Dies kann beispielsweise der Zugriff auf eine Kamera sein oder auch die Einbindung eines Google Services wie Google Maps.
…oder Umstieg mit Entwicklungserfahrung?
Erfahrene Developer finden sich in Dart schnell zurecht. Die Sprache wirkt sofort vertraut, sollte man mit einer der gängigen Software-Entwicklungssprachen der letzten zehn Jahre gearbeitet haben. Viele Elemente in Flutter wirken ebenfalls vertraut, als habe das Entwicklungsteam hinter Flutter gezielt bewährte Elemente aus verschiedenen Sprachen übernommen, damit die Reise in den neuen Schuhen möglichst wenig schmerzende Füße beschert. Das alles wirkt nicht wahllos, sondern als habe es ein klares, durchdachtes Konzept. So entsteht eine syntaktisch elegante und konsistente Sprache, die das Beste aus vielen Welten vereint.
Auch bei der Wahl der IDE haben Developer häufig keinen Umstiegs-Ärger zu erleiden. Die IDEs von JetBrains oder Microsoft haben sich als Standards für Flutter-Developer etabliert. Vom Anbieter JetBrains kommt der IntelliJ IDEA Ableger Android Studio, welche sich entgegen der Namensgebung für die App-Entwicklung für alle Plattformen eignet. Von Microsoft stammt Visual Studio Code. Mit diesen bieten beide Hersteller bestens geeignete, frei zugängliche Werkzeuge für die Flutter-Entwicklung an.
Natürlich gibt es auch hier eine Lernkurve zu überwinden. Doch es fühlt sich nicht an, als müsste man einen unbezwingbaren Berg erklimmen. Vielmehr erinnert es an eine gut geplante Wanderung: Man kann seine eigene Ausrüstung mitbringen – sei es Wissen aus anderen Sprachen oder erprobte Workflows – oder sich ganz auf die vom Bergführer bereitgestellte Ausrüstung verlassen. Der Weg ist klar markiert, und der Aufstieg macht Freude, ohne frustrierend zu sein.
Typen und Typensicherheit
Dart ist eine statisch typisierte Sprache, was bedeutet, dass der Typ von Variablen zur Kompilierzeit bekannt ist. Wie ein gut geschnürter Wanderschuh sorgt Typensicherheit dafür, dass viele Fehler bereits während der Entwicklung erkannt werden, bevor der Code überhaupt ausgeführt wird. Flutter profitiert direkt von diesem Konzept, da es Developer hilft, robuste und zuverlässige Anwendungen zu schreiben.
Variablen besitzen klar definierte Typen, wodurch potenzielle Stolperfallen – etwa die Verwendung von falschen Datentypen oder unerwarteten Null-Werten – bereits während der Entwicklung erkannt und vermieden werden. Die Einführung von Null-Safety wirkt wie ein zuverlässiges Sicherungsseil: Null-Werte können nur dort auftreten, wo sie ausdrücklich erlaubt sind, und verhindern so gefährliche Abstürze durch NullPointerExceptions – ein Problem, das in anderen Sprachen häufig vorkommt.
Das Typensystem von Dart bietet sowohl starke Typisierung für präzise Kontrolle als auch Typinferenz, die wie ein erfahrener Bergführer den Entwicklerinnen und Entwicklern Arbeit abnimmt, indem sie Typen automatisch ableitet. So bleibt der Code kompakt und übersichtlich, ohne auf Sicherheit zu verzichten:
int count = 42; // Explizite Typisierung
var message = "Hallo, SMF!"; // Typinferenz, Dart erkennt String
Die Typensicherheit in Dart ermöglicht es auch, komplexe Datenstrukturen sicher zu handhaben, indem generische Typen verwendet werden, z. B. in Listen oder Maps:
var names = <String>{}; // Set of Strings
List<String> sentence = ["SMF", "Macht", "Das"]; // Liste von Strings
Dieses durchdachte Typensystem schafft nicht nur Vertrauen in den Code, sondern verbessert auch die Zusammenarbeit in Teams, da der Code leichter lesbar und verständlich ist und zudem den Testaufwand verringert.
Statische Code Analyse
Flutter bietet von Haus aus eine leistungsstarke statische Code-Analyse, die wie ein zuverlässiger Kompass fungiert und Developer sicher durch die Herausforderungen des Entwicklungsprozesses leitet. Über die Konfiguration der analysis_options.yaml können Regeln flexibel an die Anforderungen eines Projekts angepasst oder erweitert werden. Dies ermöglicht es, sowohl auf projektspezifische Coding-Standards als auch auf teaminterne Konventionen Rücksicht zu nehmen.
include: package:flutter_lints/flutter.yaml
# Strict tyoe checks
analyzer:
plugins:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
# Lint rules
linter:
rules:
- cancel_subscriptions
Die Code-Analyse sorgt dafür, dass über die gesamte Codebasis hinweg ein konsistenter Stil gewahrt bleibt – wie gut markierte Wege auf unserer Bergtour. Dadurch bleibt der Code nicht nur lesbar und strukturiert, sondern auch leicht wartbar, selbst wenn das Projekt wächst. Syntaktische und logische Fehler werden frühzeitig erkannt, bevor sie zu größeren Problemen führen, sodass die Developer nicht plötzlich in einer Sackgasse landen.
So kann es helfen, Fehlerquellen ausfindig zu machen oder „Code Smells“ zu entlarven. Diese Meldungen rangieren dabei von Hinweis (z.B. Uppercase statt camelCase Konstante), über Warnung (z. B. ungenutzte Ressource) zu Kritisch (z. B. Typisierungsfehler). Diese Ergebnisse werden vom Analyser ständig aufgelistet. Die Dokumentation zu einem Fehler kann direkt aus der UI heraus geöffnet oder eine vorgeschlagene Lösung angewandt werden.
Der Analyser kann zusätzlich mit Plugins erweitert werden, um so noch mehr Metriken aus dem Code zu gewinnen, beispielsweise die Code Complexities.
Für Teams bei SMF ist die Einhaltung eines gemeinsamen Stils entscheidend, um effizient zusammenzuarbeiten – wie eine erfahrene Gruppe von Bergsteigerinnen und Bergsteigern, die sich auf klare Anweisungen und abgestimmte Ausrüstung verlässt. Dank der Integration in IDEs wie Android Studio, IntelliJ oder VS Code erhalten Developer in Echtzeit Feedback zu ihrem Code, und umgehen damit bereits in erster Instanz vermeidbare Fehler, was langwierige Code-Reviews vereinfacht. Mit Flutter haben alle die nötigen Werkzeuge, um den Gipfel sauber und sicher zu erreichen.
Integration von Design Patterns
Flutter-Überblick: Wer sich für die Entwicklung mit Flutter entscheidet, wird sich am besten direkt mit Design Patterns auseinandersetzen. Diese Muster sind wie erprobte Routenführer, die den Weg zu einer erfolgreichen und effizienten App-Entwicklung weisen. Sie helfen dabei, typische Herausforderungen zu meistern, und machen aus einem guten Code einen regelrechten Gipfelsturm.
Flutter bietet die perfekte Ausrüstung: Viele bewährte Ansätze sind bereits in die Bibliotheken und Werkzeuge integriert und lassen sich leicht anwenden. Hier ein Blick auf die verbreitetsten Patterns, die unserer Erfahrung nach jeder Entwicklerin und jedem Entwickler dabei helfen, die Höhen der App-Entwicklung zu erklimmen.
- Beliebtheit – Zustandsverwaltung und Dependency Injection
- BLoC (Business Logic Component) – Zustandsverwaltung. Insbesondere im Zusammenspiel mit dem genannten Provider ein mächtiges Werkzeug
- Singleton für globale Instanzen wie z. B. Services
- Builder – zum Erstellen von komplexen oder umfangreichen Objekten
Cubit: eine BLoC-Komponente die einen Zustand ausgibt
import 'package:flutter_bloc/flutter_bloc.dart';
class SomeCubit extends Cubit<bool> {
SomeCubit() : super(false);
///
/// swap the current state and emit
///
void swap() => emit(!state);
}
Provider: eine Komponente die den Zustand eines BLoC bereitstellt
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:temp/some_cubit.dart';
import 'package:temp/temp.dart';
class TempScaf extends StatelessWidget {
const TempScaf({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SomeCubit(), // provide the Cubit/BLoC to the context
child: const SomeTestTree(),
);
}
}
Builder: eine Komponente die auf Änderungen reagiert
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:temp/some_cubit.dart';
class SomeTestTree extends StatefulWidget {
const SomeTestTree({super.key});
@override
State<SomeTestTree> createState() => _SomeTestTreeState();
}
class _SomeTestTreeState extends State<SomeTestTree> {
@override
Widget build(BuildContext context) {
return BlocBuilder(
bloc: context.read<SomeCubit>(), // rebuild according to state
builder: (context, bool isActive) {
if (isActive) {
return const Text('Enabled.');
}
return const Text('Disabled.');
},
);
}
}
Während sich zum Beispiel ein BlocBuilder ausschließlich um die Darstellung einer Eigenschaft kümmert, reagiert der ihm übergeordnete Bloc (hier in Form eines Cubit) auf Events, verarbeitet diese und gibt den entsprechenden state aus. Dieser Zustand (state) wird durch einen BlocProvider bereitgestellt, der den Bloc für alle darunterliegenden Widgets im Kontext verfügbar macht.
Was zuerst unnötig komplex erscheint, erweist sich in der Praxis wie der Helfer, der die sich verknotenden Seile voneinander trennt. Dieses Prinzip trennt die Logik vollständig von den anzeigenden Elementen, was nicht nur für eine klare Struktur sorgt, sondern auch maximale Flexibilität bei der Entwicklung ermöglicht.
Der Einsatz dieser Patterns hilft Strukturen innerhalb großer und kleiner Projekte zu schaffen, sie wartbar und erweiterbar zu halten. Wenn gemeinsame Strukturen innerhalb eines Teams von Entwicklerinnen und Entwicklern existieren, werden Logiken sichtbar und Wartungszyklen reduziert.
Funktionalität erweitern mit Abhängigkeiten
Um den Berg sicher bezwingen zu können, benötigen wir eine Seilschaft, auf die wir uns verlassen können: eine Gruppe, die ihre Erfahrung und Werkzeuge mit uns teilt. Diese Seilschaft stellt die Flutter Community dar, die kostenlos Erweiterungen zur Verfügung stellt.
pub.dev ist die zentrale Plattform für Dart- und Flutter-Developer, um Pakete und Bibliotheken zu finden, die Entwicklung effizienter machen. Mit Tausenden von Open-Source-Paketen bietet pub.dev Lösungen für nahezu jede Anforderung, von State Management (z. B. provider, BLoC) über Netzwerkkommunikation (http, dio) bis hin zu Animationen und UI-sowie gerätespezifischen Komponenten. Es finden sich dort sogar ganze Spiele-Engines (flame).
Die Plattform ermöglicht es Developer, Pakete einfach in ihre Projekte zu integrieren und auf simple Weise Updates zu verwalten. So kann ein Projekt jederzeit mit Feature-, Stabilitäts- und nicht zuletzt Sicherheitsupdates aktuell gehalten werden. Die zentrale Verwaltung wie auch die direkte Integration von Dokumentation, Quellcode, oder auch Listen der transitiven Abhängigkeiten[2] machen pub.dev zum wichtigsten Werkzeug der Flutter-Entwicklung.
Dabei werden die Veröffentlichungen mit Metriken wie
- Provider – Zustandsverwaltung und Dependency Injection
- tatsächliche aktuelle Nutzung (Anzahl der Apps, die innerhalb von 60 Tagen ein Paket eingebunden haben)
- und statische Analyse (Reihe von Kriterien wie Dokumentation, Konventionen Plattformunterstützung etc.)
bewertet, die eine grobe Einschätzung über den Zustand einer Abhängigkeit geben können. Exotischere Libraries, wie beispielsweise die Einbindung von POS-Druckern, sind demnach weiter hinten im Gesamtrating. Innerhalb eines bestimmten Suchbegriffes bekommen sie aber dennoch Gewicht. Es bedeutet also nicht unbedingt, dass ein Paket mit einer niedrigen Punktzahl schlecht ist, es kann aber bedeuten, dass mehr Entwicklungsarbeit nötig ist, dieses effizient nutzen zu können.
Konfiguration der Abhängigkeiten
Die Integration von Paketen aus pub.dev in Flutter-Projekte ist einfach und effizient. Dazu wird das gewünschte Paket in die pubspec.yaml -Datei unter dependencies hinzugefügt. Diese Datei ist das zentrale Konfigurationselement in der beinahe alle Einstellungen zusammengeführt werden.
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.5 # update up to <9.0.0
retrofit: 4.0.1 # fixe version
someother:
path: /some/path/someother #lokal
andanother:
git:
url: git@github.com:sothathappened/andanother.git # from git
Nach dem Speichern der Datei kann Flutter automatisch flutter pub get ausführen, um die Abhängigkeiten zu aktualisieren und vorzuhalten. Dabei können auch fixe Versionen, Generationen oder einfach bei jedem Build immer die aktuellste Version nachgeladen werden. Hier können auch lokale und fremd gehostete Abhängigkeiten eingebunden werden.
Anschließend kann das Paket direkt im Code importiert und genutzt werden. Diese einfache Handhabung erlaubt es Entwicklerinnen und Entwicklern, schnell auf leistungsstarke Bibliotheken zuzugreifen und sie ohne komplexe Konfiguration in ihre Projekte einzubinden, was die Entwicklung erheblich beschleunigt.
Vorteil durch Geschwindigkeit
Seine Stärken kann Flutter dann ausspielen, wenn es um Entwicklungsgeschwindigkeit geht. Mit der Hot Reload-Funktion können Developer die Auswirkung von Codeänderungen in Echtzeit sehen, ohne die App neu zu starten, was Iterationen beschleunigt und somit den Aufwand der Entwicklung senken kann. Dabei wird der State der App beibehalten. Zudem unterstützt noch die Hot Restart-Funktion mit einem sehr schnellen Neustart der App, sollte der State dann doch zurückgesetzt werden müssen. Dies ist zwar auch in anderen Frameworks wie beispielsweise React Native oder auch in der nativen Android-Entwicklung möglich, doch die Effizienz mit der dies über alle Plattformen hinweg implementiert ist, überzeugt.
Die reichhaltige Widget-Bibliothek, der Plattform angepasst oder individuell gestaltet, und der deklarative Ansatz erlauben es, komplexe UI-Elemente effizient zu erstellen. Zudem eliminiert Flutter durch seine eigene Rendering-Engine viele plattformspezifische Herausforderungen, wie das Erstellen von Dialogen.
Hierdurch können Developer mehr Zeit auf die App-Logik und weniger auf plattformspezifische Anpassungen verwenden. Flutter nutzt die Skia Rendering Engine, die unabhängig von den nativen UI-Komponenten der Plattform arbeitet und die gesamte Benutzeroberfläche selbst zeichnet. Dies ermöglicht pixelgenaue Kontrolle über das Design und garantiert eine einheitliche Darstellung und Funktionalität auf allen Plattformen – von Android und iOS bis hin zu Web und Desktop.
Ein großer Vorteil ist, dass Entwicklerinnen und Entwickler keine separaten Anpassungen für unterschiedliche Betriebssysteme vornehmen müssen, da Flutter plattformübergreifende Features wie Gestensteuerung, Animationen und Textdarstellung konsistent implementiert. Die Rendering Engine stellt sicher, dass Widgets immer identisch aussehen und reagieren, unabhängig davon, ob die App auf einem hochauflösenden Android Smartphone oder einem älteren iPad betrieben wird.
Darüber hinaus bietet die Engine eine beeindruckende Performance, da sie direkt mit dem Grafik-Hardware-Stack der Plattform kommuniziert. Dadurch wird eine flüssige Benutzererfahrung ermöglicht, selbst bei komplexen Animationen oder grafisch intensiven Apps. Dieser Ansatz erlaubt es Entwicklerinnen und Entwicklern, sich voll und ganz auf die Darstellung und Logik ihrer Anwendungen zu konzentrieren, ohne sich mit den Eigenheiten der Zielplattformen auseinandersetzen zu müssen.
Ist dennoch eine plattformabhängige Darstellung gewünscht, wie beispielsweise im Android (Material Design)/iOS (Cupertino)-Kontext, so ist dies durch die Einbindung der entsprechenden Packages möglich, um den Usern bekannte UI-Elemente anzubieten.
Mit dieser Architektur macht Flutter den Traum wahr, eine wirklich einheitliche plattformübergreifende Entwicklung zu ermöglichen – ohne Kompromisse bei Design, Funktionalität oder Leistung. Dies führt zu einer eklatanten Verkürzung der Entwicklungszyklen und einer schnelleren Markteinführung.
Widgets und der Widget-Tree
Im Kern von Flutters Performance steht ein einfaches, aber kraftvolles Konzept: Alles ist ein Widget. Widgets sind die Bausteine, aus denen jede Benutzeroberfläche in Flutter besteht. Ob eine einfache Schalfläche, ein Textfeld oder eine komplexe Animation – alles wird als Widget dargestellt. Diese Flexibilität ermöglicht, benutzerdefinierte, wiederverwendbare und hochgradig anpassbare Komponenten bei der Entwicklung zu erstellen.
Alle Widgets in einer Flutter-App sind Teil des sogenannten Widget-Tree, einer hierarchischen Struktur, welche die Beziehung zwischen den verschiedenen Elementen der App definiert. Der Widget-Tree beschreibt jedoch nur die Logik und Struktur der UI – er wird nicht bei jeder Änderung vollständig neu gerendert. Flutter unterscheidet hier zwischen Widget-Tree, Element-Tree und Render-Tree, wobei der Widget-Tree deklarativ bleibt und keine direkten Rendering-Aufgaben übernimmt.
Der tatsächliche Rendering-Prozess ist effizient gestaltet: Der Render-Tree, der für die Darstellung auf dem Bildschirm zuständig ist, wird nur dann angepasst, wenn sich ein Zustand ändert, der sich auf die visuelle Darstellung auswirkt. Widgets selbst sind unveränderlich (immutable), was bedeutet, dass sie bei Änderungen ersetzt werden. Flutter vergleicht dabei den neuen Widget-Tree mit dem bestehenden Element-Tree, um nur die betroffenen Teile des Render-Tree neu zu zeichnen. Dadurch wird eine hohe Performance erreicht, auch bei komplexen UI-Strukturen.
Ein einfacher Widget-Tree könnte beispielsweise so aussehen:
Center(
child: Text(
'Hallo SMF!',
style: TextStyle(fontSize: 24),
),
);
In diesem Beispiel wird Text als Kind von Center dargestellt, und TextStyle definiert die Eigenschaften des Textes. Solange keine Änderungen vorgenommen werden, bleibt der Render-Tree stabil und muss nicht erneut gezeichnet werden. Das spart Ressourcen.
Dieser deklarative Ansatz macht Flutter nicht nur intuitiv, sondern auch leistungsstark. Developer können beschreiben, was sie darstellen möchten, während Flutter sich um das Wie kümmert. Dieses Prinzip ermöglicht wartbaren Code und eine flüssige Nutzungserfahrung, selbst auf Geräten mit begrenzten Ressourcen.
Starten Sie Ihr App-Projekt mit Flutter
Mit Flutter zum Gipfel der App-Entwicklung: Nutzen Sie die Vorteile von Flutter für Ihre nächste App-Entwicklung! Unsere Flutter-Experts bei SMF unterstützen Sie dabei, maßgeschneiderte und performante Anwendungen für alle Plattformen zu realisieren. Profitieren Sie von unserer Erfahrung und bringen Sie Ihre App-Idee mit uns zum Erfolg.
Kontaktieren Sie uns jetzt für eine unverbindliche Beratung und erfahren Sie, wie wir gemeinsam Ihre App-Idee verwirklichen können.
* Pflicht für alle Anfragen zu unseren Angeboten.
Testing und Debugging
Flutter legt großen Wert darauf, robuste und qualitativ hochwertige Apps zu ermöglichen, und stellt dafür ein Testing- und Debugging-Toolset zur Verfügung. Ob Unit-, Widget- oder Integrationstests – Flutter bietet alles, um die Route zum Gipfel des Mount Flutter gründlich abzusichern. Mit der flutter_test -Bibliothek können einzelne Funktionen oder Klassen in der Entwicklung getestet werden, während Widget-Tests sicherstellen, dass die Oberfläche stabil bleibt, egal wie steinig der Weg wird. Integrationstests prüfen schließlich das Zusammenspiel der verschiedenen Teile einer App, um sicherzugehen, dass der gesamte Weg abgesichert ist.
Beim Debugging ist Flutter wie ein erfahrener Bergführer, der klare Anweisungen gibt: Die Integration von Debug-Tools in IDEs wie VS Code und Android Studio erlaubt es, Breakpoints zu setzen, den Codezustand zu inspizieren oder Exceptions präzise zu analysieren.

Die Flutter DevTools bieten zudem tiefergehende Einblicke, von Performance-Analysen bis hin zur Visualisierung der UI-Hierarchie. Es ist, als hätte man Fernglas, Lupe und Kompass in einem, um den besten Weg durch schwieriges Gelände zu finden, und am Wegesrand auch mal einen Blick auf die Fauna unter den Steinen werfen zu können.
Auch im Umgang mit Fehlern zeigt sich das Framework als verlässlicher Begleiter. Klare Fehlermeldungen und hilfreiche Stack-Traces sorgen dafür, dass Probleme schnell identifiziert und behoben werden können. Mit Funktionen wie Hot Reload und Hot Restartist es, als könnte man an Ort und Stelle innehalten, Anpassungen vornehmen und den Aufstieg direkt fortsetzen, ohne wertvolle Zeit zu verlieren.
Flutter liefert die nötige Ausrüstung, um jedes Projekt zuverlässig zu testen und auftretende Probleme effizient zu lösen . Das ist der Schlüssel, um Apps nicht nur schnell, sondern auch stabil und sicher bis zum Gipfel des Erfolgs zu bringen.
Performance-Tuning
In der App-Entwicklung geht es nicht nur darum, dass Anwendungen funktionieren – sie sollen sich auch flüssig und ressourcenschonend verhalten. Flutter gibt Developer von Beginn an Werkzeuge und bewährte Praktiken an die Hand, um diese Ziele zu erreichen.
Performance-Tuning ist dabei wie die Vorbereitung einer Expedition: Mit der richtigen Planung und einem genauen Blick auf die Details vermeidet man unnötige Hindernisse und schafft eine reibungslose Erfahrung für die User.
User Experience first
User einer App stehen im Fokus der Entwicklung. Nicht umsonst werden Entwicklungsschritte häufig über User Stories, also aus der Anwendungsperspektive erklärbar gemacht. Benutzerinnen und Benutzer bemerken sofort, wenn eine App „ruckelt“, Eingaben verzögert annimmt oder langsam lädt. Besonders auf Geräten mit begrenzten Ressourcen – etwa älteren Smartphones oder schwächer ausgestatteten Tablets wird das Thema Leistung entscheidend. Hier zeigt sich die Stärke von Flutter: Mit seiner effizienten Rendering-Engine und dem Fokus auf Geschwindigkeit ist es von Grund auf darauf ausgelegt, auf einer Vielzahl von Geräten flüssig ausgeführt werden zu können.
Developer werden bei der Suche nach Performance-Problemen intensiv durch die Bordmittel von Flutter unterstützt. Neben den üblichen Debugging Tools gibt es eine ganze Suite an Performance- und Datenflussanalysetools in Form der Flutter & Dart DevTools welche mit dem SDK ausgeliefert werden.
Die DevTools unterstützen unter anderem bei
- Inspektion des Layouts und State
- Diagnose der UI Performance
- CPU Profiling
- Network Profiling
- Debugging
- Speicheranalyse
Grundlegende Prinzipien für bessere Performance
In SMF-Flutter-Projekten ist eine optimale Performance bei herausragender User Experience von großer Bedeutung. Dafür setzen wir auf einige grundlegende Prinzipien der Entwicklung:
1. Sorgfältige Planung der Architektur
Eine durchdachte Struktur und klare Trennung von Zuständigkeiten im Code helfen nicht nur, die App einfacher zu warten, sondern reduzieren auch unnötige Berechnungen oder Wiederholungen. Wer sauber baut, schafft eine stabile Basis für künftige Optimierungen.
2. Reduktion auf das Wesentliche
Nicht jede Funktion muss sofort verfügbar sein, und nicht jede Ressource muss sofort geladen werden. Flutter ermöglicht es, Inhalte und Prozesse zu priorisieren und so eine schnelle Reaktionszeit sicherzustellen – ein entscheidender Faktor für ein angenehmes Benutzererlebnis.
3. Regelmäßige Überprüfung
Wie bei einer Wanderung sollte man immer wieder innehalten, um die Route zu überprüfen. Tools wie Flutters Entwicklungswerkzeuge helfen, mögliche Engpässe oder ungenutzte Ressourcen frühzeitig zu identifizieren.
4. Die Perspektive der User einnehmen
Performance ist mehr als Zahlen und Statistiken. Es geht darum, dass sich die App für den Nutzer intuitiv und reibungslos anfühlt. Ein schlanker Aufbau, schnelle Ladezeiten und direkte Reaktionen auf Interaktionen machen hier den Unterschied, ebenso wie eine intuitiv strukturierte Oberflächengestaltung.
Der Weg zur optimalen Performance
Performance-Tuning ist kein einmaliger Schritt, sondern ein kontinuierlicher Prozess. Er beginnt bei der ersten Planung und begleitet die gesamte Entwicklung. Flutter unterstützt Developer mit seinen Werkzeugen dabei, diese Route den Berg hinauf Schritt für Schritt zu optimieren – ohne dabei unnötigen Ballast mit sich zu tragen.
Realitäten der Cross Platform-Entwicklung mit Flutter
„Flutter ermöglicht eine außergewöhnlich schnelle App-Entwicklung, da Flutter eine einzige Codebasis für iOS, Android, Web und Desktop definiert.“
So lautet die Theorie und in vielen Fällen trifft sie auch zu. Doch in der Praxis lohnt es sich, etwas genauer hinzusehen. Gerade bei komplexeren Projekten können sich Fallstricke auftun, die bei einer zu euphorischen Herangehensweise übersehen werden.
Während Vanilla Flutter problemlos auf alle Plattformen ausgeliefert werden kann, ist es in der Realität selten, dass ein Projekt ohne zusätzliche Bibliotheken auskommt. Zwar ist das Angebot auf pub.dev dank der stabilen und engagierten Community enorm reichhaltig, doch nicht jede Bibliothek ist für alle Plattformen entwickelt oder ausreichend getestet. Deshalb sollte man bereits in der Planungsphase genau prüfen, welche Anforderungen die Zielplattformen stellen und ob die benötigten Pakete kompatibel sind.
Für Projekte mit nur einer Zielplattform gestaltet sich dies vergleichsweise einfach. Auf pub.dev kann man Pakete nach Plattform filtern und so sicherstellen, dass die Abhängigkeiten passen. Für mobile Plattformen und Web ist die Auswahl in der Regel sehr umfassend und passende Pakete sind oft schnell gefunden. Für Desktop-Ziele ist das Angebot noch etwas eingeschränkt, doch auch hier lassen sich meist geeignete Pakete finden.
Komplexer wird es, wenn eine Anwendung mehrere Plattformen gleichzeitig bedienen soll – beispielsweise eine Windows-App, die auch unter mac OS betrieben und vielleicht sogar als Web-App verfügbar sein soll. In solchen Szenarien ist ein genauer Blick auf die Abhängigkeiten entscheidend, um Probleme frühzeitig zu erkennen. Einige Bibliotheken unterstützen zwar mehrere Plattformen, aber nicht immer alle gewünschten Kombinationen.
Hier kann es nötig sein eigene Anpassungen oder Erweiterungen zu entwickeln. Jedoch sind diese Szenarien in den letzten Jahren sehr zurückgegangen, da durch die fortschreitende Verbreitung der Plattform eine immer größer werdende Anzahl von Use-Cases abgedeckt worden sind.
Interessant kann der Aufstieg auch werden, wenn verschiedene Apps in einem gemeinsamen App-Kontext entwickelt werden sollen. So können beispielsweise ein Web Backend und eine Mobile App ein gemeinsames, selbst entwickeltes Plugin zur Autorisierung oder eine gemeinsame Anzeige-Elemente-Bibliothek nutzen. Diese Konsolidierung spart Ressourcen durch verminderten Wartungsbedarf.
Flutter bleibt auch in komplexen Szenarien ein starkes Werkzeug, wenn man die Planung sorgfältig angeht und sich der spezifischen Anforderungen bewusst ist. Mit einer durchdachten Auswahl der Bibliotheken und einer regelmäßigen Überprüfung der Kompatibilität lassen sich selbst ambitionierte (nicht nur) Cross Platform-Projekte erfolgreich realisieren.
Integration in bestehende Systeme
Die Integration von Flutter in ein bestehendes System mag auf den ersten Blick eine Herausforderung sein, doch Flutter wurde so konzipiert, dass es flexibel und anpassungsfähig ist, auch in komplexen Setups. Es gibt mehrere Möglichkeiten, Flutter in eine bestehende Architektur einzubinden, sei es schrittweise oder als vollständige Migration.
Schrittweise Einführung mit Flutter Modules
Eine der größten Stärken von Flutter ist die Möglichkeit, es schrittweise in bestehende Projekte zu integrieren. Mit Flutter Modules können spezifische Teile einer App, beispielsweise ein neuer Bildschirm oder ein Feature, mit Flutter implementiert werden, während der Rest der Anwendung in der bestehenden nativen Sprache (Java, Kotlin, Swift, Objective-C) bleibt. Flutter bietet hierfür Unterstützung durch Add-to-App-Ansätze, die es ermöglichen, Flutter in bestehende iOS- oder Android-Projekte einzubinden. Dies ist ideal für Projekte, bei denen eine komplette Neuentwicklung vorerst nicht in Frage kommt.
Integration über APIs und Services
Flutter lässt sich hervorragend mit bestehenden Backend-Systemen und APIs verbinden. Über HTTP-Requests oder WebSockets kann Flutter nahtlos mit REST- oder GraphQL-APIs interagieren. Auch die Einbindung von bestehenden Authentifizierungslösungen, Datenbanken oder Drittanbieterservices wie Firebase oder AWS ist einfach umzusetzen. Das erlaubt es Entwicklerinnen und Entwicklern, Flutter-Apps problemlos in bestehende Datenflüsse und Business-Logiken zu integrieren.
Interoperabilität mit nativen Funktionen
Dank Platform Channels können Flutter-Apps direkt mit nativen Code-Komponenten kommunizieren. Dies ermöglicht es, bestehende native Features wie Kamera-APIs, Zahlungs-Gateways oder andere plattformspezifische Funktionen weiterzuverwenden, ohne dass alles in Flutter neu implementiert werden muss.
Flutter bietet hier einen klar definierten Weg, um die Brücke zwischen Dart und nativen Systemen zu schlagen.
UI-Kohärenz und bestehendes Design
Ein weiterer Vorteil von Flutter ist die Möglichkeit, ein bestehendes UI-Design zu übernehmen. Flutter unterstützt flexible und präzise Anpassungen, sodass es problemlos möglich ist, die Benutzeroberfläche einer vorhandenen Anwendung nachzubilden und ein einheitliches Nutzererlebnis zu schaffen. Gleichzeitig lassen sich neue Features mit modernem Design ergänzen, ohne dass die alte Struktur vollständig geändert werden muss.
Warum also Flutter für bestehende Systeme?
Die Integration von Flutter bedeutet nicht automatisch, dass ein kompletter Systemwechsel nötig ist. Vielmehr bietet Flutter Entwicklerinnen und Entwicklern die Möglichkeit, existierende Systeme effizient zu erweitern, alte Anwendungen zu modernisieren oder neue Funktionen zu implementieren, ohne das Rad neu zu erfinden. Dieser Ansatz minimiert Risiken und ermöglicht eine schrittweise Einführung, während gleichzeitig die Performance und das Nutzererlebnis verbessert werden können.
Aber auch noch Dart lernen?
Das ist eine berechtigte Frage von denen, die sich mit Flutter beschäftigen: „Lohnt es sich, eine Sprache wie Dart zu lernen, die scheinbar ausschließlich im Kontext von Flutter genutzt wird?“ Auf den ersten Blick mag dies stimmen, doch ein genauerer Blick zeigt, dass Dart nicht nur ein integraler Bestandteil von Flutter ist, sondern auch eigenständig viel Potenzial bietet.
Dart wurde mit dem Ziel entwickelt, einfach erlernbar zu sein und eine effiziente Umsetzung zu ermöglichen. Die Syntax wirkt vertraut, wenn bereits Erfahrungen mit Sprachen wie Java, JavaScript oder C# vorliegen, wodurch der Einstieg für viele in der Entwicklung angenehm ist. Als Sprache ist Dart nicht nur modern und gut durchdacht, sondern auch vielseitig: Es kann sowohl client- als auch serverseitig eingesetzt werden, beispielsweise mit Frameworks wie Dart Frog für Backend-Entwicklung.
Doch selbst wenn man Dart in erster Linie für Flutter nutzt, zahlt sich das Lernen aus. Flutter ist nicht nur eines der führenden Cross-Platform-Frameworks [1-1], sondern wächst stetig, mit einer engagierten Community und großem industriellen Rückhalt [3]. Die Investition in Dart ist daher nicht nur eine Wette auf Flutter, sondern eine Entscheidung für eine zukunftssichere Technologie, die in der Lage ist, einen zentralen Platz in der Softwareentwicklung einzunehmen. Wer sich auf Dart einlässt, investiert in Effizienz, Modernität und die Möglichkeit, mit Flutter innovative Apps für unterschiedlichste Plattformen zu entwickeln.
All die Begeisterung hat einen Grund: Ein Fallbeispiel
Um die hier beschriebene Begeisterung für die Entwicklung mit Flutter auch mit einem Hintergrund zu versehen, folgt hier ein Beispiel aus dem SMF-Alltag. Für interne Zwecke wurde eine App benötigt, die in der Lage ist, viele QR-Codes und Barcodes gleichzeitig zu erfassen. Übliche QR-Code-Scanner erkennen in der Regel nur einzelne Codes und bieten wenig Flexibilität beim Export der erfassten Daten.
Anforderungen im Überblick
Im ersten Use Case-Gespräch ergaben sich folgende Anforderungen:
- Eine App für Android und iOS
- Gleichzeitige Erfassung von mehr als 10 QR- und Barcodes, gemischt
- Möglichkeit, mehrere Gruppen solcher Codes nacheinander zu scannen
- Export der Daten als .csv, um sie später weiterzuverarbeiten
Das Hauptproblem stellte hier die Anforderung dar, mehrere Codes gleichzeitig zu erfassen., die Machbarkeitsrecherche dauerte jedoch nicht lange. Nach kurzer Zeit wurde auf pub.dev ein passendes Paket namens flutter_zxing gefunden, das diesen Anwendungsfall abdeckt. Mit der Kommandozeilenanweisung flutter create –org de.smf scan_tool wurde das Projekt initialisiert. Zu diesem Zeitpunkt war dadurch bereits eine lauffähige App für Android und iOS erstellt, die nun an die spezifischen Anforderungen angepasst werden konnte. Um die Funktionsfähigkeit sicherzustellen, wurde der Android Emulator (Android 13) in Android Studio gestartet und das Projekt darauf getestet.
Zusammenstellung der Abhängigkeiten
Die pubspec.yaml -Datei wurde um Abhängigkeiten ergänzt, die sowohl das State Management als auch die QR-Scanner-Funktionalität abdecken. Da von Beginn an klar war, dass Dateien gespeichert werden müssen und ein anspruchsvolleres State Management für die Sequenzen der Scans notwendig ist, wurden folgende Pakete integriert:
dependencies:
flutter:
sdk: flutter
built_collection: ^5.1.1 # komplexe immutable models
file_picker: 8.0.7 # Dateiablage
flutter_bloc: ^8.1.6 # State Management
flutter_zxing: ^1.8.2 # QR / Barcodes
Die Dokumentation auf pub.dev beschreibt ReaderWidget als zentrales Widget für die
QR-/Barcode-Erkennung. Daher wurde eine einfache Testseite implementiert, um die Funktionalität zu prüfen:
import 'package:flutter/material.dart';
import 'package:flutter_zxing/flutter_zxing.dart';
class TestPage extends StatelessWidget {
const TestPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: ReaderWidget(
isMultiScan: true,
onMultiScan: (Codes scan) {
for (var code in scan.codes){
print(code.text);
}
},
),
);
}
}
Diese Testseite wurde in der main.dart als Startpunkt der App definiert, und die Anwendung im Emulator getestet. Für den Kameratest wurde dem Emulator ein Bild mit verschiedenen Codes zugewiesen.
void main() {
runApp(const SMFApp());
}
class SMFApp extends StatelessWidget {
const SMFApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SMF Scan',
home: const TestPage();
);
}
}
Technischer Durchstich
An diesem Punkt war die primäre Funktionalität der App bereits implementiert: Beim Start öffnete sich der QR-Code-Reader und erkannte die Codes, die vor die Kamera gehalten wurden (zunächst nur als Ausgabe im Log).
Da keine Barcodes als Testbilder für den Emulator verfügbar waren, wurde die App auf ein Android-Testgerät des Entwicklers „deployed“. Innerhalb weniger Augenblicke konnte das Gerät QR- und Barcodes in der Umgebung scannen und so die Funktionalität mit einem realen Anwendungsfall überprüfen.
Prototypenentwicklung
Darauf aufbauend wurde dann Datenmodelle entwickelt, welche die Scans in Gruppen speicherten. Mithilfe des BLoC Patterns wurden diese Daten jederzeit abrufbar vorgehalten. Es wurde ein einfacher Service zur Dateiablage entwickelt. Zuletzt wurden dann je eine Seite für Start- und Scanseite entwickelt. Die Startseite zeigt auch die Daten der bereits erstellten Scans an und kann diese über einen Button speichern.
Zur Einordnung
Zwischen dem ersten Gespräch mit dem Auftraggeber und dem funktionierenden Scan auf dem Handy lagen weniger als zwei Stunden. Natürlich handelt es sich an diesem Punkt nicht um eine voll entwickelte App, sondern bestenfalls um ein MVP[4]. Dennoch lieferte das Projekt in kürzester Zeit Antworten auf Lösungsansatzfragen der primären Anforderungen – ein Beweis für die Effizienz, mit der sich Apps mit Flutter entwickeln lassen.
Der eigentliche Prototyp mit gesichertem State-Handling, der Handvoll einfacher Seiten und Funktionen wie dem Speichern der erfassten Daten, benötigte dann nur wenig länger. Dieser kam dem endgültigen Produkt sehr schnell sehr nah, und musste nur minimal an die spezifischen Anforderungen des Auftraggebers angepasst werden.
Bereit für den Gipfel?
Flutter ist mehr als nur ein Framework. Es ist eine Werkstatt, die es Entwicklerinnen und Entwicklern ermöglicht, ihre Ideen schnell und effizient in die Realität umzusetzen. Mit seiner Vielseitigkeit, der starken Community und der modernen Technologie bietet es alles, was man braucht, um erfolgreich und plattformübergreifend Apps zu entwickeln.
Ob wir am Anfang unserer Reise stehen, bestehende Projekte erweitern möchten oder einfach neugierig auf neue Möglichkeiten sind – Flutter ist bereit, uns auf diesem Weg zu begleiten. Also, warum warten? Schnüren wir die Schuhe, packen unseren Rucksack und wagen den ersten Schritt.
Haben Sie Fragen zu diesem Fachartikel oder möchten mehr über unsere Expertise in Dart und Flutter-Entwicklung erfahren? Wir stehen Ihnen gerne zur Verfügung und unterstützen Sie beim Erklimmen des Gipfels.
* Pflicht für alle Anfragen zu unseren Angeboten.
Weiterführende Links
- 2023: meist genutztes Cross Platform Framework (46%) lt. Statista
- Transitive Abhängigkeit beschreibt eine indirekte Abhängigkeit, die über eine direkte Abhängigkeit eingebracht wird. Beispiel: Wenn dein Projekt Bibliothek A nutzt und Bibliothek A wiederum Bibliothek B benötigt, ist B eine transitive Abhängigkeit deines Projekts
- Neben Googles eigenen Entwicklungen wie Google Pay, Google Earth oder Family Link setzen auch Byte Dance, ebay, Phillips Hue, Toyota, iRobot, Alibaba und viele Andere mit ihren Entwicklungen auf Flutter.
- In der Softwareentwicklung wird der Begriff Minimum Viable Product (MVP) verwendet, um einen minimalen Zustand eines funktionierenden Prototyps zu beschreiben. Ein MVP ist eine Version eines Produkts, die gerade genug Funktionen bietet, um den Nutzern einen Wert zu bieten und gleichzeitig Feedback für zukünftige Entwicklungen zu sammeln