使用本地数据库值初始化变量

Initialize a variable with local database value

我想用本地 sql 数据库中的值初始化一个变量。这是代码:

class _SettingsState extends State<Settings>{

  String morning = 'empty';

  @override
  void initState() {
    super.initState();
    initAsync();
  }

  void initAsync() async{
    morning = await DatabaseHelper.instance.queryOrario(1);
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Container(
        child: Text(morning),
      ),
    );

}

问题是当我第一次到达这个页面时,我有这个错误:

A non-null String must be provided to a Text widget.

参考行:child: Text(morning), 然后,当我热重新加载页面时,代码工作正常。为什么?我究竟做错了什么?有办法做我想做的事吗?

(我假设 morning 的默认值 'empty' 是您在将其发布到此处之前添加到代码中的内容,并且它的实际默认值为 null。否则,它会得到你得到的错误对你来说毫无意义。)

问题是您的小部件在未来有机会完成之前正在初始化和构建。当您为 morning 分配值时,小部件已经构建完成。因此,当构建小部件时,morning 仍然为空。并且 Flutter 严重反对为 Text 小部件提供空值。

而不是依赖于竞争条件(你的代码的两部分首先完成,你希望它们按特定的顺序完成),使用 FutureBuilder 这样你就可以安全地执行 futures并让您的小部件在完成后自行更新:

class _SettingsState extends State<Settings>{
  @override
  void initState() {
    super.initState();
  }

  Future<String> initAsync() async {
    String result = await DatabaseHelper.instance.queryOrario(1);
    return result;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<String>(
        future: initAsync(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return CircularProgressIndicator();
          }
          return Text(snapshot.data);
        },
      ),
    );
  }
}