FutureBuilder 构建函数不能返回 Null 错误

Posted

技术标签:

【中文标题】FutureBuilder 构建函数不能返回 Null 错误【英文标题】:FutureBuilder build function must not return Null Error 【发布时间】:2021-02-05 05:45:09 【问题描述】:

我正在学习颤振,在练习中我构建了一个应用程序,该应用程序很少出现下面提到的错误。

我无法确定返回错误的部分以及为什么我很少收到此错误,并且我的应用程序在其他时间都可以正常工作而不会出现此错误。

请注意,即使我在主屏幕呈现几秒钟后收到此错误,然后应用程序运行良好。因此,我觉得错误在加载部分,我附上了我的 SpinKitRotatingCircle 在容器中,但它没有解决问题。


在 MyApp StatelessWidget 中,我将创建 MaterialApp 3 次(一次用于成功,一次用于挂起,一次用于错误)。他们是我可以将这些合并到一个材料应用程序中的一种方式吗?


代码:

void main() 
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  @override
  Widget build(BuildContext context) 
    // return MaterialApp(
    //   home: Wrapper(),
    // );
    return FutureBuilder(
      future: _initialization,
      builder: (context, snapshot) 
        if (snapshot.hasError) 
          return MaterialApp(
            home: Scaffold(
              backgroundColor: Colors.brown[100],
              appBar: AppBar(
                backgroundColor: Colors.brown[400],
                title: Text('Error Loading Brew Crew'),
                centerTitle: true,
              ),
              body: Center(
                  child: AlertDialog(
                title: Text('Error Loading Brew Crew'),
                content: Text(snapshot.error.toString()),
                actions: <Widget>[
                  FlatButton(
                    onPressed: () => exit(0),
                    child: Text('OK'),
                  ),
                ],
              )),
            ),
          );
        
        if (snapshot.connectionState == ConnectionState.done) 
          return StreamProvider<User>.value(
            value: AuthService().user,
            child: MaterialApp(
              home: Wrapper(),
            ),
          );
        
//Loading
        print('Initializing Flutter');
        MaterialApp(
          home: Scaffold(
            backgroundColor: Colors.brown[100],
            appBar: AppBar(
              backgroundColor: Colors.brown[400],
              title: Text('Loading Brew Crew'),
              centerTitle: true,
            ),
            body: Center(
                child: SpinKitRotatingCircle(
              color: Colors.black,
              size: 50.0,
            )),
          ),
        );
      ,
    );
  

错误:

【问题讨论】:

你应该做一个MaterialApp(),在home里面,你可以用FutureBuilder这个小部件,你现在的结构很糟糕。 【参考方案1】:

Firebase.initializeApp() 是一个异步函数,因此在一段时间内它不会有值。

在此期间,您会看到上述错误。

initializeApp 完成并返回 FirebaseApp 对象时,您的 FutureBuilder 将使用该对象进行重建。

然后你的 FutureBuilder 的这一部分被执行:

if (snapshot.connectionState == ConnectionState.done) 
          return StreamProvider<User>.value(
            value: AuthService().user,
            child: MaterialApp(
              home: Wrapper(),
            ),
          );
        

但在此之前,您的 has.error 子句不正确,因此不会运行也不会返回任何内容。

在 FutureBuilder 的底部,您有:

 MaterialApp(
          home: Scaffold(
            backgroundColor: Colors.brown[100],
            appBar: AppBar(
              backgroundColor: Colors.brown[400],
              title: Text('Loading Brew Crew'),
              centerTitle: true,
            ),
            body: Center(
                child: SpinKitRotatingCircle(
              color: Colors.black,
              size: 50.0,
            )),
          ),
        );

请注意,您创建了一个 MaterialApp,但您还没有return MaterialApp

这就是为什么显示红色大错误屏幕的原因和原因,因为您的 FutureBuilder 没有返回任何小部件并且您不能返回任何内容。

您已经多次重复 MaterialApp 小部件,这会在您的代码中添加一些噪音,并且没有必要。也许尝试这样的事情:

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.brown[100],
        appBar: AppBar(
          backgroundColor: Colors.brown[400],
          title: Text('Loading Brew Crew'),
          centerTitle: true,
        ),
        body: FutureBuilder(
          builder: (context, snapshot) 
            if (snapshot.hasError) 
              return Center(
                  child: AlertDialog(
                    title: Text('Error Loading Brew Crew'),
                    content: Text(snapshot.error.toString()),
                    actions: <Widget>[
                      FlatButton(
                        onPressed: () => exit(0),
                        child: Text('OK'),
                      ),
                    ],
                  ));
            
            if (snapshot.hasData) 
              return StreamProvider<User>.value(
                value: AuthService().user,
                child: Wrapper(),
              );
            
            return Center(
                child: SpinKitRotatingCircle(
                  color: Colors.black,
                  size: 50.0)
            );
          ,
        ),
      ),
    );
  

【讨论】:

【参考方案2】:

你有 if (snapshot.hasError) if (snapshot.connectionState == ConnectionState.done) 返回一些东西。 但是在两个if 之后,你的MaterialApp 没有返回。 因此,如果您的快照不能跳转到两个 if,您的代码将不会返回任何内容。 只需在print('Initializing Flutter'); 下将return 添加到MaterialApp

【讨论】:

以上是关于FutureBuilder 构建函数不能返回 Null 错误的主要内容,如果未能解决你的问题,请参考以下文章

Firestore 查询正在返回数据,但 Futurebuilder 说它不能为空

使用 Mockito 的 FutureBuilder 快照数据为空 - Flutter

Dismissible 和 FutureBuilder 不能一起工作

来自 FutureBuilder 的 Navigator.pop

FlutterFuture 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )

构建期间调用的 setState() 或 markNeedsBuild()