Flutter:共享首选项在启动时为null
问题:共享的首选项bool值正在null
启动,即使prefs.getBool('myBool')
返回时我已经给它提供了一个值null
(尽管我的共享的首选项值应该已经设置并保存)。但是,它在我按下按钮时就起作用了(我想是因为它已经完成了异步代码的运行)。
问题:如何强制共享首选项在启动时加载(因此,我的值不是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
将进行打印。
回答:
您的问题是您快速连续调用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),
),
),
],
),
),
),
);
}
}
以上是 Flutter:共享首选项在启动时为null 的全部内容, 来源链接: utcz.com/qa/409329.html