Flutter -- Tutorial Teil 6 Provider Part 2
In Part 1 zum Thema Provider haben wir den Code vorbereitet, auf den wir das "Muster" Provider anwenden möchten.
Noch einmal zur Erinnerung: Der Code wurde in Visual Studio Code getestet, sollte aber auch in Android Studio problemlos laufen. Der Beispiel Code wurde dem Video von RetroPortalStudio entnommen. Ich empfehle sich das Video anzuschauen, vorausgesetzt man besitzt genügend Englisch Kenntnisse, um dem Audio Kommentar zu folgen.
Noch einmal zur Erinnerung: Der Code wurde in Visual Studio Code getestet, sollte aber auch in Android Studio problemlos laufen. Der Beispiel Code wurde dem Video von RetroPortalStudio entnommen. Ich empfehle sich das Video anzuschauen, vorausgesetzt man besitzt genügend Englisch Kenntnisse, um dem Audio Kommentar zu folgen.
1 2 3 4 5 | import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'wetterinfo.dart'; void main() => runApp(MeineApp()); |
Dieses Widget besitzt auch einen builder: Eintrag, der nicht NULL sein darf. Diesem Builder müssen wir, wie oft in Flutter, einen context übergeben und lassen gleichzeitig eine Instanz unserer WetterInfo Klasse erstellen:
1 2 3 4 | Widget build(BuildContext context) {
return ChangeNotifierProvider(
builder: (context)=>WetterInfo(),
child: Scaffold
|
Wer sich schon mit dem Thema "BLoC Pattern" beschäftigt hat, wird hier von der Struktur her, schon Ähnlichkeiten entdecken.
Wir haben also jetzt unseren Scaffold und alle nachfolgenden Widget in ein ChangeNotifierProvider Widget eingebetet. Gleichzeitig wird das WetterInfo Objekt, das wir mit diesem Widget erzeugt haben, für alle nachfolgenden Widgets sichtbar.
Aber wie wird es sichtbar, beziehungsweise, wie greifen wir darauf zu ?
Beginnen wir mit dem FloatingActionButton. Wir möchten das wenn der Benutzer auf diesen Button klickt oder tippt, sich die Messeinheit von Celsius auf Fahrenheit ändert, oder umgekehrt. In einem ersten Schritt müssen wir also sicher stellen, das unser Button Widget Zugriff auf unser WetterInfo Objekt nehmen kann:
1 2 3 4 5 6 7 8 | class MeinFliegenderActionButton extends StatelessWidget { @override Widget build(BuildContext context) { var wetterInfo = Provider.of<WetterInfo>(context); return FloatingActionButton( |
Wenn wir den Code anschauen fällt sofort Provider.of<WetterInfo>(context); auf. Der context wird ja in unserer Widget Hierarchie immer weitergegeben. Bei default übernimmt Flutter aus diesem context die Werte, die es braucht um das aktuelle Widget aufzubauen bzw einzubinden. Daten die aber nicht automatisch aus dem context übernommen werden, obwohl vorhanden, müssen wir explizit einbinden um sie verwenden zu können. Der Code oben weist der Variable wetterInfo das Objekt WetterInfo zu, welches aus dem context bezogen wird.
Provider.of können wir durch das einbinden von provider.dart verwenden. In grösseren Applikationen könnte es durchaus sein, das wir mehrere Objekte haben, die wir integrieren müssen. Durch die Angabe des Typs, in diesem Fall <WetterInfo> stellen wir sicher, das wir den benötigten bekommen.
Was wir jetzt implementieren müssen, ist der Coder der ausgeführt wird, wenn der Benutzer den Button benutzt:
1 2 3 4 5 6 | return FloatingActionButton( backgroundColor: Colors.pink, onPressed: (){ String neuerTemperaturTyp = wetterInfo.tempTyp == "Celsius"?"Fahrenheit":"Celsius"; wetterInfo.temperaturTyp = neuerTemperaturTyp; }, |
Wie funktioniert der Code oben ?
Wir erstellen eine neue String Variable.
wetterInfo.tempTyp ruft den entsprechenden Getter unserer WetterInfo Klasse auf und liefert den aktuellen Eintrag als String. Das Ergebnis wird mit "Celsius" verglichen. Wenn true wird unserer Variabel neuerTemperaturTyp der String Fahrenheit zugewiesen. Falls false, wird der String Celsius zugewiesen.
Mit wetterInfo.temperaturTyp = neuerTemperaturTyp; benutzen wir den entsprechenden Setter unserer Klasse und weisen unserem WetterInfo Objekt den aktuellen String zu.
Mit diesem Code haben wir also dafür gesorgt, das sich der String tempTyp in unserer WetterInfo Objekt abwechselnd ändert, jedesmal wenn der Button benutzt wird. Jetzt müssen wir den geänderten String auch auf den Bildschirm bringen:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class MeinSpeziellerText extends StatelessWidget { @override Widget build(BuildContext context) { var wetterInfo = Provider.of<WetterInfo>(context); return Padding( padding: const EdgeInsets.all(8.0), child: Text(wetterInfo.tempTyp), ); } } |
Im Code oben benutzen wir wieder Provider.of um Zugriff auf unser WetterInfo Objekt zu haben. Den statischen Text im Text(...) Widget ersetzen wir durch das Ergebnis eines Auslesens, des entsprechenden WetterInfo Objekt Eintrags.
Jetzt müssen wir im Vergleich zu Part 1 über Provider noch eine Ergänzung in unserer WetterInfo Klasse machen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import 'package:flutter/foundation.dart'; class WetterInfo with ChangeNotifier { String _tempTyp = "Celsius"; int _temperaturWert = 25; int get temperaturWert => _temperaturWert; String get tempTyp => _tempTyp; set temperatur(int neueTemp){ _temperaturWert = neueTemp; notifyListeners(); } set temperaturTyp(String neuerTyp){ _tempTyp = neuerTyp; notifyListeners(); } } |
Natürlich brauchen beide Setter eine notifyListeners() Funktion.
Fazit: In diesem Beispiel Code haben wir jetzt das Widget MeinSpeziellerInhalt nicht mit eingebunden. Der Code zeigt aber das Prinzipielle. Die Variante in diesem Beispiel arbeitet mit dem Zugriff über den context. Es gibt noch eine weitere Variante, aber das wird Thema eines anderen Artikels sein. Wer den Code über GitHub beziehen möchte klickt hier.
Bis Bald !
Kommentare
Kommentar veröffentlichen