Flutter 颤振-如何导航到异步值上的另一页

Flutter 颤振-如何导航到异步值上的另一页,flutter,triggers,setstate,Flutter,Triggers,Setstate,我试图在应用程序初始启动时显示一个启动屏幕,直到我正确检索了所有数据。它一出现,我就想导航到应用程序的主屏幕 不幸的是,我找不到一个好方法来触发运行这种导航的方法 这是我用来测试这个想法的代码。具体来说,我想运行命令Navigator.pushNamed(上下文“home”)当变量shouldProceed变为真时。现在,我能想到的唯一方法是显示一个按钮,我需要按下该按钮来触发导航代码: import 'package:flutter/material.dart'; import 'packag

我试图在应用程序初始启动时显示一个启动屏幕,直到我正确检索了所有数据。它一出现,我就想导航到应用程序的主屏幕

不幸的是,我找不到一个好方法来触发运行这种导航的方法

这是我用来测试这个想法的代码。具体来说,我想运行命令
Navigator.pushNamed(上下文“home”)当变量
shouldProceed
变为真时。现在,我能想到的唯一方法是显示一个按钮,我需要按下该按钮来触发导航代码:

import 'package:flutter/material.dart';
import 'package:catalogo/src/navigationPage.dart';

class RouteSplash extends StatefulWidget {
  @override
  _RouteSplashState createState() => _RouteSplashState();
}

class _RouteSplashState extends State<RouteSplash> {
  ValueNotifier<bool> buttonTrigger;
  bool shouldProceed = false;

  _fetchPrefs() async { //this simulates the asynchronous function
    await Future.delayed(Duration(
        seconds:
            1)); // dummy code showing the wait period while getting the preferences
    setState(() {
      shouldProceed = true; //got the prefs; ready to navigate to next page.
    });
  }

  @override
  void initState() {
    super.initState();
    _fetchPrefs(); // getting prefs etc.
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: shouldProceed
            ? RaisedButton(
                onPressed: () {
                  print("entered Main");
                  Navigator.pushNamed(context, 'home'); // <----- I want this to be triggered by shouldProceed directly
                },
                child: Text("Continue"),
              )
            : CircularProgressIndicator(), //show splash screen here instead of progress indicator
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“package:catalogo/src/navigationPage.dart”;
类RouteSplash扩展StatefulWidget{
@凌驾
_RouteSplashState createState()=>\u RouteSplashState();
}
类_RouteSplashState扩展状态{
ValueNotifier按钮触发器;
bool shouldProceed=false;
_fetchPrefs()async{//这模拟了异步函数
等待未来。延迟(持续时间)(
秒数:
1) );//获取首选项时显示等待时间的伪代码
设置状态(){
shouldProceed=true;//已获取prefs;准备导航到下一页。
});
}
@凌驾
void initState(){
super.initState();
_fetchPrefs();//获取prefs等。
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:应该吃吗
?升起按钮(
已按下:(){
打印(“主输入”);

Navigator.pushNamed(context'home');//您所要做的就是在获得首选项后,导航到屏幕并让build方法生成一个进度指示器

试试这个:

_fetchPrefs() async {
  await Future.delayed(Duration(seconds: 1));
  Navigator.of(context).pushNamed("home"); //stateful widgets give you context
}
以下是您的新构建方法:

@override
Widget build(BuildContext context) {
  return Center(child: CircularProgressIndicator());
}

我制作了一个DartPad来说明:

创建一个小部件,它可以像我的ProgressBar代码一样显示或隐藏。显示和隐藏基于计时器,或者当api的数据加载完成时

    ProgressBar progressBar = new ProgressBar();
    progressBar.show(context);

     Provider.of<Api>(context, listen: false)
      .loadData(context, param)
      .then((data) {
      progressBar.hide();
      Provider.of<Api>(context, listen: false).dataCache.login = loginValue;
      Navigator.pop(context, true);
      Navigator.pushNamed(context, "/home");
    }
  });
ProgressBar ProgressBar=newprogressbar();
progressBar.show(上下文);
Provider.of(上下文,侦听:false)
.loadData(上下文,参数)
.然后((数据){
progressBar.hide();
Provider.of(context,listen:false).dataCache.login=loginValue;
pop(上下文,true);
Navigator.pushNamed(上下文,“/home”);
}
});
将ProgressBar代码替换为初始屏幕:

 class ProgressBar {

    OverlayEntry _progressOverlayEntry;

    void show(BuildContext context){
        _progressOverlayEntry = _createdProgressEntry(context);
        Overlay.of(context).insert(_progressOverlayEntry);
    }

    void hide(){
        if(_progressOverlayEntry != null){
        _progressOverlayEntry.remove();
        _progressOverlayEntry = null;
        }
    }

    OverlayEntry _createdProgressEntry(BuildContext context) =>
        OverlayEntry(
            builder: (BuildContext context) =>
                Stack(
                    children: <Widget>[
                    Container(
                        color: Colors.white.withOpacity(0.6),
                    ),
                    Positioned(
                        top: screenHeight(context) / 2,
                        left: screenWidth(context) / 2,
                        child: CircularProgressIndicator(),
                    )

                    ],

                )
        );

    double screenHeight(BuildContext context) =>
        MediaQuery.of(context).size.height;

    double screenWidth(BuildContext context) =>
        MediaQuery.of(context).size.width;

  }
类进度条{
过度进入(OverlayEntry);;
无效显示(构建上下文){
_ProgressOverlyEntry=\u createdProgressEntry(上下文);
覆盖.of(上下文).insert(_progressOverlayEntry);
}
void hide(){
如果(_progressOverlyEntry!=null){
_progressOverlayEntry.remove();
_ProgressOverlyEntry=null;
}
}
OverlyEntry\u createdProgressEntry(构建上下文上下文)=>
过度进入(
生成器:(BuildContext上下文)=>
堆叠(
儿童:[
容器(
颜色:颜色。白色。不透明度(0.6),
),
定位(
顶部:屏幕高度(上下文)/2,
左:屏幕宽度(上下文)/2,
子对象:CircularProgressIndicator(),
)
],
)
);
双屏幕高度(BuildContext上下文)=>
MediaQuery.of(context).size.height;
双屏幕宽度(BuildContext上下文)=>
MediaQuery.of(context).size.width;
}

感谢您的及时回复。我认为我对_fetchPrefs的模拟不够准确。数据实际上来自以下内容:shouldProceed=Provider.of(上下文,listen:true).shouldProceed;这就是为什么我希望跟踪外部值更改时的方法触发器。我会将此标记为已回答(因为它在原始问题的范围内),并使用提供程序创建一个新问题。