Verwenden von Flutter von Google für eine wirklich plattformübergreifende mobile Entwicklung
Veröffentlicht: 2022-03-10Flutter ist ein plattformübergreifendes Open-Source-Framework für mobile Entwicklung von Google. Es ermöglicht die Erstellung hochleistungsfähiger, ansprechender Anwendungen für iOS und Android aus einer einzigen Codebasis. Es ist auch die Entwicklungsplattform für das kommende Fuchsia-Betriebssystem von Google. Darüber hinaus ist es so konzipiert, dass es über benutzerdefinierte Flutter-Engine-Einbetter auf andere Plattformen gebracht werden kann.
Warum Flutter erstellt wurde und warum Sie es verwenden sollten
Plattformübergreifende Toolkits haben in der Vergangenheit einen von zwei Ansätzen verfolgt:
- Sie verpacken eine Webansicht in einer nativen App und erstellen die Anwendung, als wäre es eine Website.
- Sie umhüllen native Plattformsteuerelemente und bieten eine gewisse plattformübergreifende Abstraktion darüber.
Flutter verfolgt einen anderen Ansatz, um die mobile Entwicklung zu verbessern. Es bietet ein Framework, gegen das Anwendungsentwickler arbeiten, und eine Engine mit einer portablen Laufzeit zum Hosten von Anwendungen. Das Framework baut auf der Skia-Grafikbibliothek auf und stellt Widgets bereit, die tatsächlich gerendert werden, anstatt nur Wrapper für native Steuerelemente zu sein.
Dieser Ansatz bietet die Flexibilität, eine plattformübergreifende Anwendung auf vollständig benutzerdefinierte Weise zu erstellen, wie es die Web-Wrapper-Option bietet, bietet aber gleichzeitig eine reibungslose Leistung. Inzwischen macht die umfangreiche Widget-Bibliothek, die mit Flutter geliefert wird, zusammen mit einer Fülle von Open-Source-Widgets es zu einer sehr funktionsreichen Plattform, mit der man arbeiten kann. Einfach gesagt, Flutter ist das Beste, was mobile Entwickler für die plattformübergreifende Entwicklung mit wenig bis gar keinen Kompromissen hatten.
Pfeil
Flutter-Anwendungen sind in Dart geschrieben, einer Programmiersprache, die ursprünglich von Google entwickelt wurde. Dart ist eine objektorientierte Sprache, die sowohl Voraus- als auch Just-in-Time-Kompilierung unterstützt, wodurch sie sich gut für die Erstellung nativer Anwendungen eignet und gleichzeitig einen effizienten Entwicklungsworkflow mit Flutters Hot Reloading ermöglicht. Flutter ist kürzlich auch auf die Dart-Version 2.0 umgestiegen.
Die Dart-Sprache bietet viele der Funktionen, die auch in anderen Sprachen zu finden sind, darunter Garbage Collection, Async-await, Strong Typing, Generika sowie eine reichhaltige Standardbibliothek.
Dart bietet eine Schnittmenge von Funktionen, die Entwicklern aus verschiedenen Sprachen wie C#, JavaScript, F#, Swift und Java vertraut sein sollten. Darüber hinaus kann Dart zu Javascript kompilieren. In Kombination mit Flutter ermöglicht dies die gemeinsame Nutzung von Code über Web- und mobile Plattformen.
Historischer Zeitplan der Ereignisse
- April 2015
Flutter (ursprünglich mit dem Codenamen Sky) wird auf dem Dart Developer Summit gezeigt - November 2015
Sky in Flutter umbenannt - Februar 2018
Flutter Beta 1 auf dem Mobile World Congress 2018 angekündigt - April 2018
Flutter Beta 2 angekündigt - Mai 2018
Flutter Beta 3 auf der Google I/O angekündigt. Google gibt bekannt, dass Flutter für Produktions-Apps bereit ist
Vergleich mit anderen Entwicklungsplattformen
Apple/Android-nativ
Native Anwendungen bieten die geringste Reibung bei der Einführung neuer Funktionen. Sie neigen dazu, Benutzererfahrungen zu haben, die besser auf die jeweilige Plattform abgestimmt sind, da die Anwendungen unter Verwendung von Steuerelementen der Plattformanbieter selbst (Apple oder Google) erstellt werden und häufig den von diesen Anbietern festgelegten Designrichtlinien folgen. In den meisten Fällen werden native Anwendungen eine bessere Leistung erbringen als solche, die mit plattformübergreifenden Angeboten erstellt wurden, obwohl der Unterschied in vielen Fällen je nach der zugrunde liegenden plattformübergreifenden Technologie vernachlässigbar sein kann.
Ein großer Vorteil nativer Anwendungen besteht darin, dass sie brandneue Technologien, die Apple und Google in der Beta-Phase entwickeln, auf Wunsch sofort übernehmen können, ohne auf die Integration von Drittanbietern warten zu müssen. Der Hauptnachteil beim Erstellen nativer Anwendungen ist die fehlende plattformübergreifende Wiederverwendung von Code, was die Entwicklung teuer machen kann, wenn sie auf iOS und Android abzielt.
Nativ reagieren
React Native ermöglicht die Erstellung nativer Anwendungen mit JavaScript. Die eigentlichen Steuerelemente, die die Anwendung verwendet, sind native Plattformsteuerelemente, sodass der Endbenutzer das Gefühl einer nativen App bekommt. Für Apps, die eine Anpassung erfordern, die über das hinausgeht, was die Abstraktion von React Native bietet, könnte dennoch eine native Entwicklung erforderlich sein. In Fällen, in denen der Umfang der erforderlichen Anpassungen erheblich ist, verringert sich der Nutzen der Arbeit innerhalb der Abstraktionsschicht von React Native bis zu dem Punkt, an dem in einigen Fällen die Entwicklung der App nativ vorteilhafter wäre.
Xamarin
Bei der Erörterung von Xamarin müssen zwei verschiedene Ansätze bewertet werden. Für ihren plattformübergreifendsten Ansatz gibt es Xamarin.Forms. Obwohl sich die Technologie stark von React Native unterscheidet, bietet sie konzeptionell einen ähnlichen Ansatz, da sie native Steuerelemente abstrahiert. Ebenso hat es ähnliche Nachteile in Bezug auf die Anpassung.
Zweitens gibt es das, was viele als Xamarin-Klassiker bezeichnen. Bei diesem Ansatz werden die iOS- und Android-Produkte von Xamarin unabhängig voneinander verwendet, um plattformspezifische Funktionen zu erstellen, genau wie bei der direkten Verwendung von nativem Apple/Android, wobei im Fall von Xamarin nur C# oder F# verwendet wird. Der Vorteil von Xamarin besteht darin, dass nicht plattformspezifischer Code, Dinge wie Netzwerke, Datenzugriff, Webdienste usw. gemeinsam genutzt werden können.
Im Gegensatz zu diesen Alternativen versucht Flutter, Entwicklern eine vollständigere plattformübergreifende Lösung mit Code-Wiederverwendung, leistungsstarken, flüssigen Benutzeroberflächen und hervorragenden Tools zu bieten.
Überblick über eine Flutter-App
Erstellen einer App
Nach der Installation von Flutter ist das Erstellen einer App mit Flutter so einfach wie das Öffnen einer Befehlszeile und die Eingabe von flutter create [app_name]
, die Auswahl des Befehls „Flutter: New Project“ in VS Code oder die Auswahl von „Start a new Flutter Project“ in Android Studio oder IntelliJ.
Unabhängig davon, ob Sie eine IDE oder die Befehlszeile zusammen mit Ihrem bevorzugten Editor verwenden, bietet Ihnen die neue Flutter-Anwendungsvorlage einen guten Ausgangspunkt für eine Anwendung.
Die Anwendung bringt das flutter
/ material.dart
-Paket mit, um einige grundlegende Gerüste für die App bereitzustellen, z. B. eine Titelleiste, Materialsymbole und Themen. Es richtet auch ein zustandsbehaftetes Widget ein, um zu demonstrieren, wie die Benutzeroberfläche aktualisiert wird, wenn sich der Anwendungsstatus ändert.

Werkzeugoptionen
Flutter bietet eine unglaubliche Flexibilität in Bezug auf die Werkzeugausstattung. Anwendungen können genauso einfach über die Befehlszeile zusammen mit einem beliebigen Editor entwickelt werden, wie sie aus einer unterstützten IDE wie VS Code, Android Studio oder IntelliJ stammen können. Der zu wählende Ansatz hängt weitgehend von den Vorlieben des Entwicklers ab.
Android Studio bietet die meisten Funktionen, wie z. B. einen Flutter Inspector, um die Widgets einer laufenden Anwendung zu analysieren und die Anwendungsleistung zu überwachen. Es bietet auch mehrere Refactorings, die bei der Entwicklung einer Widget-Hierarchie praktisch sind.
VS Code bietet ein leichteres Entwicklungserlebnis, da es tendenziell schneller startet als Android Studio/IntelliJ. Jede IDE bietet integrierte Bearbeitungshilfen, wie z. B. Codevervollständigung, die das Erkunden verschiedener APIs sowie eine gute Debugging-Unterstützung ermöglichen.
Die Befehlszeile wird auch durch den flutter
-Befehl gut unterstützt, was es einfach macht, eine Anwendung zu erstellen, zu aktualisieren und zu starten, ohne dass eine andere Werkzeugabhängigkeit über einen Editor hinausgeht.

Heißes Nachladen
Unabhängig von den Werkzeugen bietet Flutter eine hervorragende Unterstützung für das Hot-Reloading einer Anwendung. Dadurch kann eine laufende Anwendung in vielen Fällen geändert werden, wobei der Status beibehalten wird, ohne dass die Anwendung angehalten, neu erstellt und erneut bereitgestellt werden muss.
Hot Reload erhöht die Entwicklungseffizienz erheblich, indem es eine schnellere Iteration ermöglicht. Es macht wirklich Spaß, mit der Plattform zu arbeiten.
Testen
Flutter enthält ein WidgetTester
Dienstprogramm, um mit Widgets aus einem Test zu interagieren. Die neue Anwendungsvorlage enthält einen Beispieltest, um zu demonstrieren, wie sie beim Erstellen eines Tests verwendet wird, wie unten gezeigt:
// Test included with the new Flutter application template import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:myapp/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(new MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); }
Verwenden von Paketen und Plugins
Flutter steht noch am Anfang, aber es gibt bereits ein reichhaltiges Entwickler-Ökosystem: Eine Fülle von Paketen und Plugins ist bereits für Entwickler verfügbar.
Um ein Paket oder Plug-in hinzuzufügen, schließen Sie einfach die Abhängigkeit in die Datei pubspec.yaml im Stammverzeichnis der Anwendung ein. Führen Sie dann flutter packages get
entweder über die Befehlszeile oder über die IDE aus, und Flutters Tools bringen alle erforderlichen Abhängigkeiten ein.
Um beispielsweise das beliebte Bildauswahl-Plug-in für Flutter zu verwenden, muss die pubspec.yaml es nur wie folgt als Abhängigkeit auflisten:
dependencies: image_picker: "^0.4.1"
Dann bringt das Ausführen von flutter packages get
alles, was Sie brauchen, um es zu nutzen, wonach es importiert und in Dart verwendet werden kann:
import 'package:image_picker/image_picker.dart';
Widgets
Alles in Flutter ist ein Widget. Dazu gehören Elemente der Benutzeroberfläche wie ListView
, TextBox
und Image
sowie andere Teile des Frameworks, einschließlich Layout, Animation, Gestenerkennung und Designs, um nur einige zu nennen.
Indem alles ein Widget ist, kann die gesamte Anwendung, die übrigens auch ein Widget ist, innerhalb der Widget-Hierarchie dargestellt werden. Eine Architektur, in der alles ein Widget ist, macht deutlich, woher bestimmte Attribute und Verhaltensweisen kommen, die auf einen Teil einer App angewendet werden. Dies unterscheidet sich von den meisten anderen Anwendungsframeworks, die Eigenschaften und Verhalten inkonsistent zuordnen und sie manchmal von anderen Komponenten in einer Hierarchie und manchmal an das Steuerelement selbst anfügen.
Einfaches UI-Widget-Beispiel
Der Einstiegspunkt zu einer Flutter-Anwendung ist die Hauptfunktion. Um ein Widget für ein Element der Benutzeroberfläche auf dem Bildschirm anzuzeigen, rufen Sie in main()
runApp()
auf und übergeben Sie ihm das Widget, das als Stamm der Widget-Hierarchie dient.
import 'package:flutter/material.dart'; void main() { runApp( Container(color: Colors.lightBlue) ); }
Dies ergibt ein hellblaues Container
-Widget, das den Bildschirm ausfüllt:


Zustandslose vs. zustandsbehaftete Widgets
Widgets gibt es in zwei Varianten: zustandslos und zustandsbehaftet. Zustandslose Widgets ändern ihren Inhalt nicht, nachdem sie erstellt und initialisiert wurden, während zustandsbehaftete Widgets einen gewissen Zustand beibehalten, der sich während der Ausführung der Anwendung ändern kann, z. B. als Reaktion auf eine Benutzerinteraktion.
In diesem Beispiel werden ein FlatButton
Widget und ein Text
-Widget auf den Bildschirm gezeichnet. Das Text
-Widget beginnt mit einer String
für seinen Status. Das Drücken der Schaltfläche führt zu einer Zustandsänderung, die dazu führt, dass das Text
-Widget aktualisiert wird und einen neuen String
anzeigt.
Um ein Widget zu kapseln, erstellen Sie eine Klasse, die entweder von StatelessWidget
oder StatefulWidget
abgeleitet ist. Der hellblaue Container
könnte beispielsweise wie folgt geschrieben werden:
class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Container(color: Colors.lightBlue); } }
Flutter ruft die Build-Methode des Widgets auf, wenn es in den Widget-Baum eingefügt wird, damit dieser Teil der Benutzeroberfläche gerendert werden kann.
Leiten Sie für ein zustandsbehaftetes Widget von StatefulWidget
ab:
class MyStatefulWidget extends StatefulWidget { MyStatefulWidget(); @override State createState() { return MyWidgetState(); } }
class MyStatefulWidget extends StatefulWidget { MyStatefulWidget(); @override State createState() { return MyWidgetState(); } }
Stateful-Widgets geben eine State
-Klasse zurück, die für den Aufbau des Widget-Baums für einen bestimmten Zustand verantwortlich ist. Wenn sich der Status ändert, wird der zugehörige Teil des Widget-Baums neu erstellt.
Im folgenden Code aktualisiert die State
-Klasse einen String
, wenn auf eine Schaltfläche geklickt wird:
class MyWidgetState extends State { String text = "some text"; @override Widget build(BuildContext context) { return Container( color: Colors.lightBlue, child: Padding( padding: const EdgeInsets.all(50.0), child: Directionality( textDirection: TextDirection.ltr, child: Column( children: [ FlatButton( child: Text('Set State'), onPressed: () { setState(() { text = "some new text"; }); }, ), Text( text, style: TextStyle(fontSize: 20.0)), ], ) ) ) ); } }
class MyWidgetState extends State { String text = "some text"; @override Widget build(BuildContext context) { return Container( color: Colors.lightBlue, child: Padding( padding: const EdgeInsets.all(50.0), child: Directionality( textDirection: TextDirection.ltr, child: Column( children: [ FlatButton( child: Text('Set State'), onPressed: () { setState(() { text = "some new text"; }); }, ), Text( text, style: TextStyle(fontSize: 20.0)), ], ) ) ) ); } }
Der Status wird in einer Funktion aktualisiert, die an setState()
wird. Wenn setState()
aufgerufen wird, kann diese Funktion jeden internen Zustand setzen, wie den String in diesem Beispiel. Dann wird die build
-Methode aufgerufen, die den Baum des Stateful-Widgets aktualisiert.

Beachten Sie auch die Verwendung des Directionality
-Widgets zum Festlegen der Textrichtung für alle Widgets in seiner Unterstruktur, die dies erfordern, wie z. B. die Text
-Widgets. Die Beispiele hier bauen Code von Grund auf neu auf, daher wird Directionality
irgendwo in der Widget-Hierarchie benötigt. Die Verwendung des MaterialApp
-Widgets, z. B. mit der Standardanwendungsvorlage, richtet die Textrichtung jedoch implizit ein.
Layout
Die runApp
Funktion bläst das Widget auf, um standardmäßig den Bildschirm auszufüllen. Um das Widget-Layout zu steuern, bietet Flutter eine Vielzahl von Layout-Widgets. Es gibt Widgets zum Ausführen von Layouts, die untergeordnete Widgets vertikal oder horizontal ausrichten, Widgets erweitern, um einen bestimmten Raum zu füllen, Widgets auf einen bestimmten Bereich beschränken, sie auf dem Bildschirm zentrieren und Widgets einander überlappen lassen.
Zwei häufig verwendete Widgets sind Row
und Column
. Diese Widgets führen Layouts aus, um ihre untergeordneten Widgets horizontal (Zeile) oder vertikal (Spalte) anzuzeigen.
Um diese Layout-Widgets zu verwenden, müssen Sie sie einfach um eine Liste von untergeordneten Widgets wickeln. mainAxisAlignment
steuert, wie die Widgets entlang der Layoutachse positioniert werden, entweder zentriert, am Anfang, am Ende oder mit verschiedenen Abstandsoptionen.
Der folgende Code zeigt, wie mehrere untergeordnete Widgets in einer Row
oder Column
werden:
class MyStatelessWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Row( //change to Column for vertical layout mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.android, size: 30.0), Icon(Icons.pets, size: 10.0), Icon(Icons.stars, size: 75.0), Icon(Icons.rowing, size: 25.0), ], ); } }

Auf Berührung reagieren
Die Berührungsinteraktion wird mit Gesten verarbeitet, die in der GestureDetector
-Klasse gekapselt sind. Da es sich auch um ein Widget handelt, ist das Hinzufügen von Gestenerkennung so einfach wie das Einschließen von untergeordneten Widgets in einen GestureDetector
.
Um beispielsweise einem Icon
eine Berührungsbehandlung hinzuzufügen, machen Sie es zu einem untergeordneten Element eines GestureDetector
und legen Sie die Handler des Detektors so fest, dass die gewünschten Gesten erfasst werden.
class MyStatelessWidget extends StatelessWidget { @override Widget build(BuildContext context) { return GestureDetector( onTap: () => print('you tapped the star'), onDoubleTap: () => print('you double tapped the star'), onLongPress: () => print('you long pressed the star'), child: Icon(Icons.stars, size: 200.0), ); } }
Wenn in diesem Fall auf das Symbol getippt, doppelt getippt oder lange gedrückt wird, wird der zugehörige Text gedruckt:
To hot reload your app on the fly, press "r". To restart the app entirely, press "R". An Observatory debugger and profiler on iPhone X is available at: https://127.0.0.1:8100/ For a more detailed help message, press "h". To quit, press "q". flutter: you tapped the star flutter: you double tapped the star flutter: you long pressed the star
Zusätzlich zu einfachen Tippgesten gibt es eine Fülle von Erkennungsfunktionen für alles, vom Schwenken und Skalieren bis hin zum Ziehen. Diese machen es sehr einfach, interaktive Anwendungen zu erstellen.
Bild
Flutter bietet auch eine Vielzahl von Widgets zum Malen, darunter solche, die die Deckkraft ändern, Beschneidungspfade festlegen und Dekorationen anwenden. Es unterstützt sogar benutzerdefiniertes Malen über das CustomPaint
Widget und die zugehörigen CustomPainter
und Canvas
-Klassen.
Ein Beispiel für ein Mal-Widget ist DecoratedBox
, das eine BoxDecoration
auf den Bildschirm malen kann. Das folgende Beispiel zeigt, wie Sie damit den Bildschirm mit einem Farbverlauf füllen:
class MyStatelessWidget extends StatelessWidget { @override Widget build(BuildContext context) { return new DecoratedBox( child: Icon(Icons.stars, size: 200.0), decoration: new BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.red, Colors.blue, Colors.green], tileMode: TileMode.mirror ), ), ); } }

Animation
Flutter enthält eine AnimationController
-Klasse, die die Animationswiedergabe im Laufe der Zeit steuert, einschließlich des Startens und Stoppens einer Animation sowie des Variierens der Werte für eine Animation. Zusätzlich gibt es ein AnimatedBuilder
-Widget, das es ermöglicht, eine Animation in Verbindung mit einem AnimationController
zu erstellen.
Jedes Widget, wie der zuvor gezeigte dekorierte Stern, kann seine Eigenschaften animieren. Wenn Sie beispielsweise den Code in ein StatefulWidget
umgestalten, da die Animation eine Zustandsänderung ist, und das Übergeben eines AnimationController
an die State
-Klasse ermöglicht, dass der animierte Wert beim Erstellen des Widgets verwendet werden kann.
class StarWidget extends StatefulWidget { @override State createState() { return StarState(); } } class StarState extends State with SingleTickerProviderStateMixin { AnimationController _ac; final double _starSize = 300.0; @override void initState() { super.initState(); _ac = new AnimationController( duration: Duration(milliseconds: 750), vsync: this, ); _ac.forward(); } @override Widget build(BuildContext context) { return new AnimatedBuilder( animation: _ac, builder: (BuildContext context, Widget child) { return DecoratedBox( child: Icon(Icons.stars, size: _ac.value * _starSize), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.red, Colors.blue, Colors.green], tileMode: TileMode.mirror ), ), ); } ); } }
class StarWidget extends StatefulWidget { @override State createState() { return StarState(); } } class StarState extends State with SingleTickerProviderStateMixin { AnimationController _ac; final double _starSize = 300.0; @override void initState() { super.initState(); _ac = new AnimationController( duration: Duration(milliseconds: 750), vsync: this, ); _ac.forward(); } @override Widget build(BuildContext context) { return new AnimatedBuilder( animation: _ac, builder: (BuildContext context, Widget child) { return DecoratedBox( child: Icon(Icons.stars, size: _ac.value * _starSize), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.red, Colors.blue, Colors.green], tileMode: TileMode.mirror ), ), ); } ); } }
class StarWidget extends StatefulWidget { @override State createState() { return StarState(); } } class StarState extends State with SingleTickerProviderStateMixin { AnimationController _ac; final double _starSize = 300.0; @override void initState() { super.initState(); _ac = new AnimationController( duration: Duration(milliseconds: 750), vsync: this, ); _ac.forward(); } @override Widget build(BuildContext context) { return new AnimatedBuilder( animation: _ac, builder: (BuildContext context, Widget child) { return DecoratedBox( child: Icon(Icons.stars, size: _ac.value * _starSize), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.red, Colors.blue, Colors.green], tileMode: TileMode.mirror ), ), ); } ); } }
In diesem Fall wird der Wert verwendet, um die Größe des Widgets zu variieren. Die builder
-Funktion wird immer dann aufgerufen, wenn sich der animierte Wert ändert, wodurch die Größe des Sterns über 750 ms variiert, wodurch eine effektive Skalierung entsteht:

Verwenden nativer Funktionen
Plattformkanäle
Um Zugriff auf native Plattform-APIs auf Android und iOS bereitzustellen, kann eine Flutter-Anwendung Plattformkanäle verwenden. Diese ermöglichen es Flutter Dart-Code, Nachrichten an die hostende iOS- oder Android-Anwendung zu senden. Viele der verfügbaren Open-Source-Plug-ins werden mithilfe von Messaging über Plattformkanäle erstellt. Um zu lernen, wie man mit Plattformkanälen arbeitet, enthält die Flutter-Dokumentation ein gutes Dokument, das den Zugriff auf native Akku-APIs demonstriert.
Fazit
Bereits in der Beta-Phase bietet Flutter eine großartige Lösung zum Erstellen plattformübergreifender Anwendungen. Mit seiner hervorragenden Werkzeugausstattung und dem Hot-Reloading bringt es ein sehr angenehmes Entwicklungserlebnis. Die Fülle an Open-Source-Paketen und die hervorragende Dokumentation erleichtern den Einstieg. Mit Blick auf die Zukunft können Flutter-Entwickler neben iOS und Android auch auf Fuchsia abzielen. In Anbetracht der Erweiterbarkeit der Engine-Architektur würde es mich nicht überraschen, wenn Flutter auch auf einer Vielzahl anderer Plattformen landen würde. Mit einer wachsenden Community ist es eine großartige Zeit, um einzusteigen.
Nächste Schritte
- Flutter installieren
- Dart Sprachreise
- Flutter-Codelabs
- Flutter Udacity-Kurs
- Artikel-Quellcode