【问题标题】:FutureBuilder doesn't wait until future completesFutureBuilder 不会等到未来完成
【发布时间】:2021-08-03 02:57:31
【问题描述】:

在我的应用程序中,我想在创建小部件之前初始化一些东西。我需要在App 类中完全做到这一点,并尝试为此目的使用 FutureBuilder。但是例如_AppBlocProviderbuild方法在initInjectionContainer()之前被调用。我的存储库尚未在 injectionContainer 中初始化,但提供程序中的 Blocs 正在尝试访问它的实例。这段代码有什么问题?

我也试过这个:

void main() {
  runApp(App());
}

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  Future<bool>? _myFuture;

  Future<bool> _init() async {
    ...
    await initInjectionContainer();
    await sl<AudioManager>().preloadFiles();
    return false;
  }

  ...

  @override
  void initState() {
    super.initState();
    _myFuture = _init();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _myFuture,
      builder: (context, _) {
        return _BlocProvider(
          child: Builder(
            builder: (context) => MaterialApp(
              title: 'Flutter Demo',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home: MainMenu(),
            ),
          ),
        );
      },
    );
  }
}

没用。

【问题讨论】:

    标签: flutter flutter-futurebuilder flutter-future


    【解决方案1】:

    FutureBuilder 不只是自动阻止或显示加载屏幕或其他任何内容。它在初始化时构建一次,然后在未来完成后再次构建。您匿名的构建器中的第二个参数对于正确处理未来状态并相应地构建至关重要。

    FutureBuilder(
      future: _someFuture(),
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          // Future not done, return a temporary loading widget
          return CircularProgressIndicator();
        }
    
        // Future is done, handle it properly
        return ...
      },
    ),
    

    话虽如此,如果您的整个应用程序需要初始化某些东西,您可以在调用runApp 之前从main 调用它,以便它们成为运行时加载过程的一部分,而不是强制执行处理它的小部件:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      await initInjectionContainer();
      await sl<AudioManager>().preloadFiles();
    
      runApp(App());
    } 
    

    现在,如果这些过程可能需要一段时间,最好使用小部件处理它们,以便您可以向用户显示加载状态,以便他们知道应用程序没有不要只是在启动时冻结。

    【讨论】:

    • 感谢您的回答。但在我的情况下,我希望能够导入我的 github 存储库并将我的应用程序与它的所有资源一起使用,比如图像等......所以在另一个包中导入这个小部件时我不能调用 main() 方法。
    • 非常感谢您的回答,我对 FutureBuilder 的理解不深是我的错。
    • @YaroBest 为什么不将所有这些资源作为资产添加到您的应用程序中?为什么要从 Github 下载它们?
    • 这是一个游戏,我希望能够在我想要的任何应用程序中使用它,只需导入它并传入它的统计存储库的实现即可。所以我所有的资源都在 lib/assets 中。
    猜你喜欢
    • 2019-10-08
    • 2015-01-07
    • 1970-01-01
    • 2022-08-16
    • 2020-12-22
    • 2013-12-14
    • 2014-07-21
    • 2019-10-25
    • 2020-03-11
    相关资源
    最近更新 更多