In meiner Flatter-App versuche ich, einen einmaligen / ersten Bildschirm zu erstellen, in dem ein Tutorial angezeigt wird, wenn die App zum ersten Mal heruntergeladen wird. Ich habe mich für Shared Preferences entschieden, um die Daten zu speichern. Aber wenn ich die App starte , erhalte ich die Meldung " Fehlgeschlagen": Der boolesche Ausdruck darf nicht null sein : Dies liegt daran , dass die Variable _seen in meinem Code nicht initialisiert wurde. Als ich weiter nachschaute, stellte ich fest, dass mein Code die Variable nach ihrer Verwendung initialisiert ein Widget erstellen. Gibt es überhaupt eine Möglichkeit, dies zu beheben?
Mein Code
void main() => runApp(Start());
class Start extends StatefulWidget
{
@override
App createState() => new App();
}
class App extends State<Start>
{
bool _seen;
@override
void initState()
{
print(1);
_checkFirstTime();
super.initState();
}
_checkFirstTime() async
{
print(1.1);
SharedPreferences prefs = await SharedPreferences.getInstance();
_seen = (prefs.getBool('seen') ?? false);
print(1.2);
}
_updateFirstTime() async
{
SharedPreferences prefs = await SharedPreferences.getInstance();
_seen = true;
prefs.setBool('seen', true);
}
Widget build(BuildContext context)
{
print(2);
bool seen = _seen;
if (_seen == false) {_updateFirstTime();}
print(2.1);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: seen ? HomeScreen() : SignUpScreen(),
);
}
}
Das eigentliche Problem hierbei ist, dass die SharedPreferences-API asynchron ist, sodass die build () -Methode erwartungsgemäß ausgelöst wird, bevor die Einstellungen geladen werden.
Es geht:
1. initState
2. _checkFirstTime (starts)
3. build
4. _checkFirstTime (completes)
Es gibt viele Möglichkeiten, wie Sie das Problem beheben können. Sie können auf false initialisieren, einen FutureBuilder verwenden, ein _isInitComplete-Flag verwenden usw.
Eine einfache Lösung könnte darin bestehen, dies oben in Ihrem Build hinzuzufügen:
if(_seen == null) return Container();
Jetzt wird eine leere Ansicht für die 4 ms oder was auch immer angezeigt wird, bis die Einstellungen abgeschlossen sind. Dies entspricht funktional der Verwendung eines FutureBuilder. Vergessen Sie nicht, setState()
am Ende anzurufen _checkFirstTime
, um eine Aktualisierung auszulösen.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen