问题:共享的首选项bool值正在null启动,即使prefs.getBool('myBool')返回时我已经给它提供了一个值null(尽管我的共享的首选项值应该已经设置并保存)。但是,它在我按下按钮时就起作用了(我想是因为它已经完成了异步代码的运行)。
null
prefs.getBool('myBool')
问题:如何强制共享首选项在启动时加载(因此,我的值不是null)而不必按下打印按钮?
示例代码:
import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() => runApp(new MyApp()); class MyApp extends StatefulWidget { MyApp({Key key}) : super(key: key); @override createState() => new MyAppState(); } class MyAppState extends State<MyApp> { final padding = const EdgeInsets.all(50.0); @override void initState() { super.initState(); MySharedPreferences.load(); MySharedPreferences.printMyBool(); } @override Widget build(BuildContext context) { return new MaterialApp( home: new Scaffold( body: new Padding( padding: padding, child: new Column( children: <Widget>[ new Padding( padding: padding, child: new RaisedButton( child: new Text('Save True'), onPressed: () => MySharedPreferences.save(myBool: true), ), ), new Padding( padding: padding, child: new RaisedButton( child: new Text('Save False'), onPressed: () => MySharedPreferences.save(myBool: false), ), ), new Padding( padding: padding, child: new RaisedButton( child: new Text('Print myBool'), onPressed: () => MySharedPreferences.printMyBool(), ), ), ], ), ), ), ); } } class MySharedPreferences { static bool _myBool; static void load() async { SharedPreferences prefs = await SharedPreferences.getInstance(); _myBool = prefs.getBool('myBool') ?? false; } static void save({myBool: bool}) async { SharedPreferences prefs = await SharedPreferences.getInstance(); _myBool = myBool; await prefs.setBool('myBool', _myBool); } static void printMyBool() { print('myBool: ${_myBool.toString()}'); } }
结果:在启动时,将myBool: null被打印。按下按钮后,myBool: false/true将进行打印。
myBool: null
myBool: false/true
您的问题是您快速连续调用load()和printMyBool()。由于load()是异步调用,因此它尚未执行任何代码,因此仅对其进行了调度。因此,printMyBool在加载主体之前执行。
无需将静态函数放在类中-只需将它们声明为顶级函数即可。另外,您实际上并不希望_myBool是全局变量- 它应该是Widget状态的一部分。这样,当您更新它时,Flutter知道要重绘树的哪些部分。
我已经对您的代码进行了重组,以删除多余的静态变量。
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() => runApp(new MyApp()); class MyApp extends StatefulWidget { MyApp({Key key}) : super(key: key); @override createState() => new MyAppState(); } const EdgeInsets pad20 = const EdgeInsets.all(20.0); const String spKey = 'myBool'; class MyAppState extends State<MyApp> { SharedPreferences sharedPreferences; bool _testValue; @override void initState() { super.initState(); SharedPreferences.getInstance().then((SharedPreferences sp) { sharedPreferences = sp; _testValue = sharedPreferences.getBool(spKey); // will be null if never previously saved if (_testValue == null) { _testValue = false; persist(_testValue); // set an initial value } setState(() {}); }); } void persist(bool value) { setState(() { _testValue = value; }); sharedPreferences?.setBool(spKey, value); } @override Widget build(BuildContext context) { return new MaterialApp( home: new Scaffold( body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Padding( padding: pad20, child: new Text( _testValue == null ? 'not ready' : _testValue.toString()), ), new Padding( padding: pad20, child: new RaisedButton( child: new Text('Save True'), onPressed: () => persist(true), ), ), new Padding( padding: pad20, child: new RaisedButton( child: new Text('Save False'), onPressed: () => persist(false), ), ), new Padding( padding: pad20, child: new RaisedButton( child: new Text('Print myBool'), onPressed: () => print(_testValue), ), ), ], ), ), ), ); } }