Flutter lernen - scoped model (2021)

 

flutterCoder
In einem älteren Artikel hatte ich bereits das Thema Statefull - / Stateless Widgets angeschnitten. Zur Auffrischung: Flutter kennt zwei Sorten von Widgets (Objekten). Solche die so angelegt sind, das sie Veränderungen umsetzen können, und solche, die nach der Erstellung in ihrem Zustand verbleiben. Da gerade die Fußball EM läuft ein Vergleich: Das Fußballfeld und die zwei Tore würden Sie über Stateless Widgets realisieren. Es bleibt immer gleich. Die Mannschaften über Statefull Widgets. Die Mannschaften wechseln, die Spieler sind andere. Jedes Mal also, wenn eine neue Mannschaft auf das Spielfeld läuft, muss Ihr Statefull Widget diese Veränderung abbilden.
Um den weiteren Artikel gut nachzuvollziehen sollten Sie bereits grundlegende Kenntnisse über Flutter bzw. Dart besitzen. Der Artikel basiert auf einem YouTube Video von Nick Manning (englisch). 

State

Von Haus aus ist Flutter so eingerichtet, das Sie den Teil des Codes, der eine Veränderung umsetzen muss, in ein Statefull Widget packen. Der Hauptteil des Codes steht dann im "State" Teil des Widgets. Hier noch einmal der Hinweis: Ein Beispiel mit der "Hausmethode" von Flutter, was Statefull Widgets angeht, finden Sie hier.

Vor allem bei grösseren Apps kann das Handling von Statefull Widgets komplex werden. Hier haben Entwickler verschiedene Erweiterungen geschrieben, die den Umgang damit vereinfachen. In diesem Artikel  werde ich scoped_model 1.1.0 verwenden.

Erweiterung einbinden

Um scoped_model verwenden zu können, müssen Sie es im pubspec.yaml File Ihres Projekts einbinden:

vscode1

Sobald Sie speichern, werden die notwendigen Dateien aus dem Internet geladen und stehen im Projekt zur Verfügung.

Mehr Ordnung

Sobald man mehr als ein paar Zeilen Code schreibt, sollte man sich Gedanken über die Struktur des eigenen Projekts machen. Mit der Zeit wird man seine ganz persönlichen Vorlieben finden. In diesem Projekt verteilen wir den Code auf verschiedene Ordner und Dateien:


main. dart enthält den Einstieg in das Programm. app.dart  den Aufruf unseres Homescreens. Beide Files befinden sich im lib Ordner.
In diesem sind auch drei neue Ordner: models, scoped_models und screens.

Die Absicht hinter dieser Struktur: In diesem Projekt haben Sie im Ordner Screen, den Ordner home und alle dazugehörigen Files. In grösseren Projekten müssen Sie eventuell mehrere Screens organisieren: home, secondscreen, loginscreen etc. Der Ordner screens könnte also alle Bildschirme enthalten, die Sie verwalten müssen. 
Das gleiche Prinzip gilt für die Ordner models und scoped_models.

Die Beispiel App

Ähnlich wie der Boiler Plate Code, der beim erzeugen eines neuen Flutter Projekts angelegt wird, werden wir eine Counter App erstellen. Nur diesmal mit drei, statt nur einem Zähler.

main.dart

Das main File enthält nur wenige Zeilen Code:

scoped model 1

Der Code enthält keine Überraschungen. 2 Importe  und der Aufruf zum Starten unserer Anwendung.

app.dart

scoped model 2

Dieser Code definiert unsere App als eine MaterialApp und trägt MeineHomePage(...) als home ein. Auch hier keine Überraschungen. Im Normalfall hätte man den Code von main.dart und app.dart in einem File erfassen können. Die Trennung dient rein der Ordnung im Projekt.

model Ordner

In einem "normalen" Statefull Widget" verwalten Sie alle zugehörigen Daten im State Teil des Widgets. Was heisst das ? Sie überwachen innerhalb dieses Widgets, ob eine Veränderung eingetretten ist. Wenn ja, reagieren Sie darauf, indem Sie einen Neuaufbau des Bildschirms veranlassen. Der einte Teil des Codes wird zum Beispiel einen Button auf den Bildschirm zeichnen, der andere Teil des Codes wird überwachen, ob der Butten geklickt wurde. Damit Sie das Programmieren können, werden Sie Variablen oder Objekte definieren und benutzen. models enthält mit counter.dart  eine Klassendefinition. Der Ordner könnte aber natürlich noch andere Definitionen enthalten, die Sie an anderer Stelle und in einem anderen Zusammenhang benötigen.

counter.dart

scoped model 3

Diese Klasse ist selbsterklärend. Bitte beachten Sie, das die Klassenvariable mit dem Wert 1 initialisiert wird. 

Was ist daran Model ?
Counter(Zaehler) ist als Klasse angelegt und erlaubt den Zugriff auf die Klassenvariable count. In counter.dart aber haben wir noch keine Methoden von scoped_model verwendet, oder eine Logik programmiert. model enthält also die Variablen / Objekt / Klassendefinitionen, die wir benötigen um scoped_model verwenden zu können. Und wieder ist diese Speicherung in einem separaten Ordner / File kein muss, sondern der Ordnung geschuldet.

scoped_counters.dart

scoped model 4

In scoped_counters.dart benutzen Sie nun scoped_model. Das Kernstück dieser Erweiterung ist das Model. Mit extends erweitern Sie diese Klasse um den Logikteil dieses Beispiels. 
In einem ersten Schritt werden drei Klassenobjekte vom Typ Counter definiert. Anschliessend die Methode increment(...) , die die jeweilige Klassenvariable um unterschiedliche Werte erhöht.
Zum Schluss wird notifyListeners(...) eingesetzt. Diese scoped_model Methode informiert alle "Zuhörer", das der State ein Update erfahren hat.

home.dart

Das Kernstück dieses Programmes:

scoped model 5

Der erste wichtige Punkt: obwohl wir den State in Flutter benutzen, brauchen Sie kein Statefull Widget ! Das hat eine gewisse Logik. Der State wird ja von scoped_model und den dadurch zur Verfügung gestellten Möglichkeiten implementiert.

In einem ersten Schritt definieren Sie eine Objektvariable (scopedCounter) vom Typ ScopedCounter. Mit der build Methode des Widgets lassen Sie sich ein ScopedModel  Widget zurückgeben, vom Typ ScopedCounter. Im model: Eintrag dieses Widgets verankern Sie die Objektvariable scopedCounter.

Später im Code werden noch drei Widgets eingebunden und ein Button. In seiner onPressed Methode benutzen Sie die increment(...) Methode der scoped_model Klasse mithilfe von der Objektvariable scopedCounter.

widget1.dart

scoped model 6

In diesem Code benutzen Sie wieder scoped_model. Mit der build(...) Methode des Widgets lassen Sie sich ein ScopedModelDescendant vom Typ ScopedCounter zurückgeben. Im Text Widgets wiederum greifen Sie auf die erste von drei Klassenvariablen von ScopedCounter zu.

Wie weiss widget1 überhaupt von unserem ScopedCounter
Diese Information stammt von home.dart.  Wenn Sie den entsprechend Code noch einmal betrachten, sehen Sie den model: Eintrag. Dieser wird weiter gereicht an widget1, wo er wiederum in der builder: Sektion des Codes eingesetzt wird.

Der Code in widget2 und widget3 ändert sich, bis auf das Text Widget, nicht.

Unten sehen Sie noch den kompletten Code. Weitere Informationen zu scoped_model finden Sie hier. Bis bald !



Kommentare

Beliebte Posts aus diesem Blog

Material Design in Flutter Teil 2

Flutter -- ohne Dart geht es nicht 2 -- einfache Variablen Typen

Dart Final Const