这个覆盖小部件无法标记为需要构建,因为框架已经在构建小部件的过程中了。

10

我已经有以下应用程序:

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(),
        }

      ),
    );
  }

}

我需要首先绘制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??
        }
        });
    }

你能帮我并展示如何在应用程序启动时绘制SplashScreen,然后从中切换到HomePage吗?

能否协助我在应用程序启动时绘制SplashScreen,并在此后切换至HomePage

2个回答

12

你需要将你的 SplashScreen() 包装在一个 StatefulWidget 中,以便你可以在 initState() 中获取数据。重要的是,将 fetch() 逻辑包装在 SchedulerBinding.instance.addPostFrameCallback() 中,以便在 initState() 中访问 BuildContext。同时,这样做可以避免在实际构建时被销毁的 RenderObjects 冲突。

以下是完整的最小示例。 编辑:你不能在 initState({}) 中使用 await。

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((_) {
      _loadDataAndNavigate()
    });
  }

  _loadDataAndNavigate() async {
    // fetch data | await this.service.fetch(x,y)
    Navigator.of(context).pushNamed('/');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SplashScreen(),
    );
  }
}

请看这里的源代码 https://gist.github.com/bubnenkoff/6afc662c2ca17f1e0905f44b6bf18f82。您需要将其翻译成中文吗? - Dmitry Bubnenkov
我需要一个进度条。有包含它的库吗?我的现有进度条正在尝试使用覆盖小部件,但无法标记。OverlayEntry _createdProgressEntry(BuildContext context) => OverlayEntry(builder: (BuildContext context) => Stack(children: <Widget>[...child: CircularProgressIndicator(), - Golden Lion

0

我使用了Splash Screen

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SplashHome(),
      routes: <String, WidgetBuilder>{
        '/HomeScreen': (BuildContext context) => new ImageHome()
      },
    );
  }
}

class SplashHome extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _SplashHome();
  }
}

const timeout = const Duration(seconds: 2);

class _SplashHome extends State<SplashHome>{

  startTimeout() {
    return new Timer(timeout, handleTimeout);
  }
  void handleTimeout() {
    Navigator.of(context).pushReplacementNamed('/HomeScreen');
  }

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

  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.lightBlue,
    );
  }
}

导入文件 import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - Junsu Cho
你能解释一下我的代码哪里出了问题吗?比如为什么你使用 home 而不是 '/': (context) => HomePage(), - Dmitry Bubnenkov
home 属性是 MaterialApp 的初始小部件。您希望在数据获取后使用 Navigator()动态更改此小部件。 - Daniel Eberl
为什么示例中使用 pushReplacementNamed?为什么要更改默认主页? - Dmitry Bubnenkov
@rollcake 我尝试采用你的例子,但是没有设置timeout就无法正常工作。我收到了错误信息:This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets - Dmitry Bubnenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接