问题:启动时共享首选项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
。
答案 0 :(得分:5)
您的问题是您快速连续调用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),
),
),
],
),
),
),
);
}
}
答案 1 :(得分:1)
添加条件??当您从偏好中获得价值时。
int intValue = prefs.getInt('intValue') ?? 0;
答案 2 :(得分:1)
import 'package:shared_preferences/shared_preferences.dart';
class MySharedPreferences {
MySharedPreferences._privateConstructor();
static final MySharedPreferences instance =
MySharedPreferences._privateConstructor();
setBooleanValue(String key, bool value) async {
SharedPreferences myPrefs = await SharedPreferences.getInstance();
myPrefs.setBool(key, value);
}
Future<bool> getBooleanValue(String key) async {
SharedPreferences myPrefs = await SharedPreferences.getInstance();
return myPrefs.getBool(key) ?? false;
}
}
MySharedPreferences.instance
.getBooleanValue("key")
.then((value) => setState(() {
val result = value;
}));
答案 3 :(得分:0)
如果共享首选项返回null,则使用条件运算符(??)分配值
IncidentDetail.PendIncidentNbr
答案 4 :(得分:0)
对于仍然遇到此问题的任何人,这是因为接受的答案中仍然存在竞争条件。
To fix it, use this package to wait for the layout to load first
答案 5 :(得分:-1)
您可以使用FutureBuilder
进行async
操作。