Ich möchte Funktionen ausführen können, sobald ein Widget fertig erstellt / geladen wurde, bin mir aber nicht sicher, wie. Mein aktueller Anwendungsfall besteht darin, zu überprüfen, ob ein Benutzer authentifiziert ist, und wenn nicht, zu einer Anmeldeansicht umzuleiten. Ich möchte nicht vorher überprüfen und entweder die Anmeldeansicht oder die Hauptansicht drücken, es muss geschehen, nachdem die Hauptansicht geladen wurde. Kann ich dazu irgendetwas verwenden?
121
build
. Build kann jederzeit mehrmals aufgerufen werden.Antworten:
Du könntest benutzen
https://github.com/slightfoot/flutter_after_layout
Dies führt eine Funktion nur einmal nach Abschluss des Layouts aus. Oder schauen Sie sich einfach die Implementierung an und fügen Sie sie Ihrem Code hinzu :-)
Welches ist im Grunde
void initState() { super.initState(); WidgetsBinding.instance .addPostFrameCallback((_) => yourFunction(context)); }
quelle
WidgetsBinding.instance.addPostFrameCallback((_) => yourFunciton(context));
funktioniert nicht mehrinitState
z. inbuild
.setState
innerhalb deryourFunction
Methode aufrufen , damit es funktioniertUPDATE: Flutter v1.8.4
Beide genannten Codes funktionieren jetzt:
import 'package:flutter/scheduler.dart'; SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
quelle
NoSuchMethodError (NoSuchMethodError: The method 'addPostFrameCallback' was called on null. Receiver: null
Es gibt drei Möglichkeiten:
1) WidgetsBinding.instance.addPostFrameCallback((_) => yourFunc(context)); 2) Future.delayed(Duration.zero, () => yourFunc(context)); 3) Timer.run(() => yourFunc(context));
Was
context
brauchte ich es für den Einsatz inScaffold.of(context)
nachdem alle meine Widgets gemacht wurden.Aber meiner bescheidenen Meinung nach ist der beste Weg, dies zu tun:
void main() async { WidgetsFlutterBinding.ensureInitialized(); //all widgets are rendered here await yourFunc(); runApp( MyApp() ); }
quelle
Flattern 1.2 - Pfeil 2.2
Gemäß den offiziellen Richtlinien und Quellen können Sie beispielsweise schreiben, wenn Sie sicher sein möchten, dass auch der letzte Rahmen Ihres Layouts gezeichnet wurde:
import 'package:flutter/scheduler.dart'; void initState() { super.initState(); if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) { SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context)); } }
quelle
Wenn Sie nach dem
componentDidMount
Äquivalent von ReactNative suchen , hat Flutter es. Es ist nicht so einfach, aber es funktioniert genauso. In Flutter behandelnWidget
s ihre Ereignisse nicht direkt. Stattdessen verwenden sie ihrState
Objekt, um dies zu tun.class MyWidget extends StatefulWidget{ @override State<StatefulWidget> createState() => MyState(this); Widget build(BuildContext context){...} //build layout here void onLoad(BuildContext context){...} //callback when layout build done } class MyState extends State<MyWidget>{ MyWidget widget; MyState(this.widget); @override Widget build(BuildContext context) => widget.build(context); @override void initState() => widget.onLoad(context); }
State.initState
Wird sofort aufgerufen, sobald der Bildschirm das Rendern des Layouts beendet hat. Und wird auch beim Hot-Reload nie wieder aufgerufen, wenn Sie sich im Debug-Modus befinden, bis die Zeit dafür explizit erreicht ist.quelle
StatefulWidget
Klasse verwenden, um dasState
Objekt wie ein Objekt zu behandeln,StatelessWidget
aber ich kann es nur empfehlen. Ich habe noch kein Problem gefunden, aber bitte versuchen Sie zuerst, alles innerhalb desState
Objekts zu implementierencomponentWillMount
unmittelbar vor dem Rendern des Layouts erfolgen. Flattern bietet eine einfachere Lösung.initState
ist sowohl für das Abrufen von Daten als auch für das gerenderte Layout ausreichend, wenn wir wissen, wie es richtig gemacht wirdIn Flatter Version 1.14.6, Dart Version 28.
Im Folgenden wird beschrieben, was für mich funktioniert hat: Sie müssen lediglich alles, was nach der Erstellungsmethode geschehen soll, in einer separaten Methode oder Funktion bündeln.
@override void initState() { super.initState(); print('hello girl'); WidgetsBinding.instance .addPostFrameCallback((_) => afterLayoutWidgetBuild()); }
quelle
Versuchen Sie SchedulerBinding,
SchedulerBinding.instance .addPostFrameCallback((_) => setState(() { isDataFetched = true; }));
quelle
Wenn Sie dies nur einmal tun möchten, tun Sie dies, da das Framework die
initState()
Methode für jedes von ihm erstellte Statusobjekt genau einmal aufruft.@override void initState() { super.initState(); WidgetsBinding.instance .addPostFrameCallback((_) => executeAfterBuildComplete(context)); }
Wenn Sie dies immer wieder wie auf der Rückseite tun oder zu einem nächsten Bildschirm usw. navigieren möchten, tun Sie dies, weil Wird
didChangeDependencies()
aufgerufen, wenn sich eine Abhängigkeit dieses Statusobjekts ändert.Wenn beispielsweise der vorherige Aufruf auf
build
einenInheritedWidget
später geänderten Aufruf verweist , ruft das Framework diese Methode auf, um dieses Objekt über die Änderung zu benachrichtigen.Diese Methode wird auch unmittelbar danach aufgerufen
initState
. Es ist sicher,BuildContext.dependOnInheritedWidgetOfExactType
von dieser Methode aufzurufen .@override void didChangeDependencies() { super.didChangeDependencies(); WidgetsBinding.instance .addPostFrameCallback((_) => executeAfterBuildComplete(context)); }
Dies ist Ihre Rückruffunktion
executeAfterBuildComplete([BuildContext context]){ print("Build Process Complete"); }
quelle
Beste Möglichkeiten, dies zu tun,
1. WidgetsBinding
WidgetsBinding.instance.addPostFrameCallback((_) { print("WidgetsBinding"); });
2. WidgetsBinding
SchedulerBinding.instance.addPostFrameCallback((_) { print("SchedulerBinding"); });
Es kann innerhalb aufgerufen
initState
werden. Beide werden nur einmal aufgerufen, nachdem die Build-Widgets mit dem Rendern fertig sind.@override void initState() { // TODO: implement initState super.initState(); print("initState"); WidgetsBinding.instance.addPostFrameCallback((_) { print("WidgetsBinding"); }); SchedulerBinding.instance.addPostFrameCallback((_) { print("SchedulerBinding"); }); }
Beide oben genannten Codes funktionieren genauso, da beide das ähnliche Bindungsframework verwenden. Für den Unterschied finden Sie den folgenden Link.
https://medium.com/flutterworld/flutter-schedulerbinding-vs-widgetsbinding-149c71cb607f
quelle