【问题标题】:Where do I run initialisation code when starting a flutter app?启动颤振应用程序时在哪里运行初始化代码?
【发布时间】:2019-09-25 06:00:09
【问题描述】:

启动 Flutter 应用时,我在哪里运行初始化代码?

void main() {

  return runApp(MaterialApp(
    title: "My Flutter App",

    theme: new ThemeData(
        primaryColor: globals.AFI_COLOUR_PINK,
                backgroundColor: Colors.white),

        home: RouteSplash(),

    ));
}

如果我想运行一些初始化代码,比如获取共享首选项,或者(在我的情况下)初始化一个包(并且我需要传入 MaterialApp 小部件的 BuildContext),那么正确的做法是什么这?

我应该将 MaterialApp 包装在 FutureBuilder 中吗?还是有更“正确”的方法?

------- 编辑 --------------------------- ------------

我现在已将初始化代码放在RouteSplash() 小部件中。但是由于我需要应用程序根目录的 BuildContext 进行初始化,所以我在 Widget build 覆盖中调用了初始化并传入 context.ancestorInheritedElementForWidgetOfExactType(MaterialApp)。因为我不需要在显示启动屏幕之前等待初始化完成,所以我没有使用Future

【问题讨论】:

    标签: flutter


    【解决方案1】:

    执行此操作的一种简单方法是将RouteSplash 作为您的初始屏幕并在其中执行如图所示的初始化代码。

    class RouteSplash extends StatefulWidget {
      @override
      _RouteSplashState createState() => _RouteSplashState();
    }
    
    class _RouteSplashState extends State<RouteSplash> {
      bool shouldProceed = false;
    
      _fetchPrefs() async {
        await Future.delayed(Duration(seconds: 1));// dummy code showing the wait period while getting the preferences
        setState(() {
          shouldProceed = true;//got the prefs; set to some value if needed
        });
      }
    
      @override
      void initState() {
        super.initState();
        _fetchPrefs();//running initialisation code; getting prefs etc.
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: shouldProceed
                ? RaisedButton(
                    onPressed: () {
                      //move to next screen and pass the prefs if you want
                    },
                    child: Text("Continue"),
                  )
                : CircularProgressIndicator(),//show splash screen here instead of progress indicator
          ),
        );
      }
    }
    

    main()里面

    void main() {
      runApp(MaterialApp(
        home: RouteSplash(),
      ));
    }
    

    注意:这只是一种方法。如果需要,您可以使用 FutureBuilder

    【讨论】:

    • 感谢您的回复。当有人花时间提供彻底的答案时,我们总是很感激。我实际上所做的与您的答案相似。将初始化代码放在RouteSplash() 中,但由于我需要应用程序根目录的BuildContext,我在build 覆盖中调用了我的等效_fetchPrefs 并传入context.ancestorInheritedElementForWidgetOfExactType(MaterialApp)。我正在考虑让它异步,但我认为我不需要等待它完成才能显示初始屏幕。
    【解决方案2】:

    要在启动时运行代码,请将其放入 main.dart。就个人而言,我就是这样做的,初始化列表等。

    【讨论】:

    • 那时我还没有创建任何小部件,因此我的基本小部件没有 BuildContext
    • 不建议将所有内容都放在 main.dart 中。
    猜你喜欢
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 2021-06-27
    相关资源
    最近更新 更多