无法将此 Overlay 小部件标记为需要构建,因为框架已在构建小部件的过程中

Dmi*_*kov 7 flutter

我有以下应用程序:

class MyAppState extends State<MyApp>
{
  TenderApiProvider _tenderApiProvider = TenderApiProvider();

  Future init() async {
     await _tenderApiProvider.getToken();  
  }
  MyAppState()
  {
    init();
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(builder: (_) => _tenderApiProvider),
      ],
      child: MaterialApp(
        title: "My App",
        routes: {
          '/': (context) => HomePage(),
          '/splash-screen': (context) => SplashScreen(),
          '/result_table': (context) => ResultDataTable(),
        }

      ),
    );
  }

}
Run Code Online (Sandbox Code Playgroud)

我需要SplashScreen在开始时首先绘制当前代码显示HomePage

在启动画面中,我需要在加载所有数据后切换到 HomePage。这是代码:

  Widget build(BuildContext context) {
    TenderApiProvider apiProv = Provider.of<TenderApiProvider>(context);
    return StreamBuilder(
        stream: apiProv.resultController,
        builder: (BuildContext context, AsyncSnapshot snapshot) {   
        //...
        if(apiProv.apiKeyLoadingState ==  ApiKeyLoadingState.Done && apiProv.regionsLoadingState == RegionsLoadingState.Done)
        {
         Navigator.of(context).pushNamed("/"); // Should it be placed in Build??
        }
        });
    }
Run Code Online (Sandbox Code Playgroud)

你能帮我显示在应用程序启动时绘制,SplashScreen然后从它切换到HomePage吗?

Dan*_*Szy 5

您需要将您的SplashScreen()内部包装起来,StatefulWidget以便您可以在initState(). 将fetch()逻辑包装在 a 中SchedulerBinding.instance.addPostFrameCallback()以访问BuildContextinside很重要initState()。此外,这样可以避免与在实际构建时被销毁的 RenderObject 发生冲突。

遵循一个完整的最小示例。

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Wrapper(),
    );
  }
}


class Wrapper extends StatefulWidget {
  @override
  _WrapperState createState() => _WrapperState();
}

class _WrapperState extends State<Wrapper> {

  @override
  void initState() {
    super.initState();
    SchedulerBinding.instance.addPostFrameCallback((_) {
      // fetch data
      Navigator.of(context).pushNamed('/');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SplashScreen(),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)