dart - Flutter:启动时共享首选项为空

问题:如果 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),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

https://stackoverflow.com/questions/49957815/

相关文章:

dart - Flutter.io (dart) - 如何创建左填充覆盖?

dart - Flutter:获取 HTML 页面的某些元素

dart - 如何在 flutter 中拆分 Dart 类?

dart - Flutter:从 Activity 上下文外部调用 startActivity()

dart - flutter 构造函数错误

dart - setState Dart/Flutter 中带有花括号的胖箭头符号

dart - 为什么 cupertino_icons 中的图标很少?

flutter - 根据另一个小部件的位置/大小定位/调整小部件的大小

dart - 如何在 flutter 搜索页面小部件中消除搜索建议?

android-studio - flutter :发布失败