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

回到顶部