Wie erstellt man Packages mit Google Flutter
In den meisten Fällen macht es Sinn, einmal geschriebenen Code über mehrere Projekte hinweg verfügbar zu machen, ohne dabei Duplikate zu erzeugen. Hierfür bietet Flutter sogenannte Packages und Plugins an. Dabei handelt es sich um eigene Arten von Projekten, die im Fall von Packages reine Dart Komponenten bereitstellen oder, im Fall eines Plugins, Android und iOS APIs zur Verfügung stellen.
In diesem Blogpost möchte ich hierzu auf die Erstellung eines Flutter Package eingehen, am Beispiel des im letzten Flutter-Blogpost animierten exensio Logos.
Package erstellen
Ein Flutter Package kann in Android Studio über Datei -> Neu -> Neues Flutter Projekt mit einem Klick auf Flutter Package erstellt werden. Nun noch den Namen, Speicherort und Beschreibung definieren und schon kann es los gehen.
Alternativ kann das Projekt auch mit dem folgenden Befehl über die Konsole erzeugt werden:
flutter create --template=package package_name
Das so erzeugte Projekt sieht auf den ersten Blick sehr ähnlich zu einem normalen Flutter Projekt aus, besitzt aber eine Hand voll wichtiger Unterschiede.
Die Ordner android und ios fehlen, da ein Package für sich alleine nicht gebaut/gestartet werden kann und auch kein Plattform spezifischer Programmcode vorgesehen ist. Bei der Entwicklung auf dem Flutter Beta-Channel gilt dasselbe für den web Ordner. Dafür existieren die neuen Dateien changelog und license, sowie kleine Besonderheiten in pubspec und dem lib-Ordner, die wir im Folgenden genauer beleuchten.
Pubspec und lib
Bereits bekannt sind der lib Ordner sowie die pubspec.yaml Datei. Wie gewohnt, können in der pubspec alle Abhängigkeiten definiert werden, die in der Implementierung innerhalb des lib Ordners Verwendung finden.
Zusätzlich können am Anfang der Datei neben name und description auch version und homepage definiert werden. Diese dienen der Information und Identifizierung bei der Weitergabe oder einer Veröffentlichung des Package auf pub.dev.
name: exensio_animated_logo
description: A animated version of the exensio logo.
version: 1.0.0
homepage: https://www.exensio.de
Einen kleinen Stolperstein bilden die Assets. Sollen mit dem Package Bilder oder andere Dateien ausgeliefert und verwendet werden, müssen zwei Punkte beachtet werden:
- Die Dateien sollten innerhalb des lib-Ordner (z.b. unter lib/assets) abgelegt werden, sodass sie garantiert mit ausgeliefert werden.
- In der pubspec.yaml müssen die Assets mit dem folgenden Pfad definiert sein (angenommen sie sind unter lib/assets abgelegt):
assets:
- packages/package_name/assets/asset_name.png
Damit können die Assets nun im aktuellen Package wie folgt verwendet werden und sind auch nach dem Einbinden in ein Flutter Projekt verfügbar:
Image.asset(‘packages/package_name/assets/asset_name.png’)
Die Implementierung erfolgt wie gewohnt im lib-Ordner. In unserem Fall ist hier die Klasse ExensioLoadingAnimation implementiert, sodass sie bei Benutzung des Package einfach verwendet werden kann.
/// A animated version of the exensio logo.
class ExensioLoadingAnimation extends StatefulWidget {
final bool runAnimation;
final double height;
final bool showSubtitle;
final int numberOfDots = 3;
ExensioLoadingAnimation(
{Key key,
this.runAnimation = true,
this.height = 80,
this.showSubtitle = true})
: super(key: key);
@override
_ExensioLoadingAnimationState createState() =>
_ExensioLoadingAnimationState();
}
...
Changelog und License
Bei der Erstellung des Package Projekts werden zusätzlich die Dateien CHANGELOG.md und LICENSE angelegt. Wie die Namen schon erahnen lassen, handelt es sich hierbei um die Beschreibung der Änderung zwischen Versionen und dem Lizenztext. Die folgenden Punkte sind nur dann wirklich relevant, wenn das Package auf pub.dev veröffentlicht werden soll. Für die Lokale Nutzung kann der Changelog aber dennoch eine gute Dokumentation darstellen.
Der Changelog ist in Markdown geschrieben und folgt dem Schema:
## [Versionsnummer] – Datum
* Beschreibung der Änderungen.
## [1.0.0] – 16.11.2020
* Initialer Release des animierten exensio Logos.
Mindestens zur aktuellen (in pubspec.yml definierten) Version sollte eine Versionsbeschreibung vorhanden sein.
Welche Lizenz zum eigenen Package passt muss individuell entschieden werden. Hilfe hierzu können Seiten wie choosealicense.com oder tldrlegal.com bieten. Flutter und Dart selbst benutzen die BSD 3-Clause "New" or "Revised" Lizenz. Müssen mehrere Lizenzen angegeben werden, zum Beispiel auf Grund eines verwendeten Plugins, so können diese mit 80 Bindestrichen abgetrennt werden.
package_1
<some license text>
--------------------------------------------------------------------------------
package_2
<some license text>
Verwendung und Veröffentlichung
Für den lokalen Einsatz ist das Package damit bereit. In einem Flutter Projekt kann es einfach über den Pfad in den Dependencies referenziert werden und steht so zur Verfügung.
dependencies:
flutter:
sdk: flutter
exensio_animated_logo:
path: /path/to/package/exensio_animated_logo
Soll das Package auf pub.dev veröffentlich werden, können alle relevanten Punkte mit dem folgenden Befehl geprüft werden.
flutter pub publish --dry-run
Sobald alle Warnungen abgehandelt sind kann das Package veröffentlicht werden. Dabei sollte man aber bedenken, dass ein einmal publiziertes Package nicht wieder gelöscht oder von der Seite entfernt werden kann, um vorhandene Abhängigkeiten nicht zu brechen.
flutter pub publish
Weitere Informationen zur Veröffentlichung über den Packagemanager sind in der offiziellen Dokumentation zu finden.
Fazit
Die Erstellung eines Flutter Package geht schnell von der Hand und ermöglicht das saubere Trennen und die Wiederverwendung von häufig genutzten Codeteilen. Lediglich die Einbindung von Assets unterscheidet sich leider von dem üblichen Vorgehen bei Projekten, diese in ein separates Verzeichnis auszulagern.
Flutter Reihe:
- Teil 1: Mobile App-Entwicklung mit Google Flutter
- Teil 2: Flutter und Dart im Einsatz für Apps – ein Erfahrungsbericht
- Teil 3: Animationen mit Flutter - das exensio Logo als Ladeanimation
- Teil 4: Flutter for Web mittels Google Cloud Bucket veröffentlichen
- Teil 5: Wie erstellt man Packages mit Google Flutter
- Teil 6: Barcodes Scannen mit Google Flutter
- Teil 7: Wie eine Google Flutter App sprechen lernt
- Teil 8: Flutter meets Video
- Teil 9: Flutter und schimmernde Skelette
- Teil 10: Flutter Design Series: Glas Morphismus
- Teil 11: App State-Management mit Flutter BLoC
- Teil 12: Mit Quick Actions Schnellzugriffe in Flutter Apps umsetzen
- Teil 13: Listen in Listen: Flutter Performance Optimierung