【问题标题】:Flutter - How to navigate to another page on an asynchronous valueFlutter - 如何导航到异步值的另一个页面
【发布时间】:2019-12-21 16:34:01
【问题描述】:

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

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

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

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

那么,简而言之,当 shouldProceed 发生变化时,如何触发运行 Navigation 代码的函数?

【问题讨论】:

    标签: flutter triggers setstate


    【解决方案1】:

    您所要做的就是在获得首选项后,只需导航到屏幕并让构建方法构建一个进度指示器。

    试试这个:

    _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 来说明:https://dartpad.dartlang.org/431fcd9a1ea5748a82506f13be042e85

    【讨论】:

    • 感谢您的及时回复。我认为我对 _fetchPrefs 的模拟不够准确。数据实际上来自于: shouldProceed = Provider.of(context, listen: true) .shouldProceed;这就是为什么我要跟踪外部值变化的方法触发器。
    • 我会将其标记为已回答(因为它在原始问题的范围内)并使用提供者创建一个新问题。
    【解决方案2】:

    创建一个可以显示或隐藏的小部件,类似于我的 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 代码:

     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;
    
      }
    

    【讨论】:

      猜你喜欢
      • 2021-09-11
      • 2020-09-03
      • 2020-09-02
      • 2020-09-26
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多