Flutter 上带有条件导航的启动屏幕

Chl*_*dro 2 android dart flutter

对于我的应用程序,如果用户已登录,我想直接将他们带入主页,如果没有登录,则将他们带入登录页面。我确信之前已经解释过这一点,但到目前为止,我还没有找到用闪屏实现它的好方法。

我现在拥有的是:一个MainPage小部件,在 上afterFirstLayout,将重定向到LoginPageHomePage。它运作良好,但有两个主要问题:

  1. 后退按钮重定向到初始屏幕。HomePage当我按或上的后退按钮时LoginPage,我会返回到初始屏幕。这很好,但我依赖于LoginPage登录多个帐户(因此,如果它们在任何其他上下文中启动,它们会在按后退按钮时退出应用程序 - 当您处于设置屏幕,无害地添加新帐户)
  2. 屏幕会冻结,直到构建下一个页面。当它运行时,我会在屏幕上显示CircularProgressIndicator,以向用户指示应用程序正在启动并且应该很快打开。这非常有帮助,因为如果我不添加它,用户可能会变得不耐烦,而只是转向另一个应用程序。问题是,通过调用afterFirstLayout,页面在转到新页面之前只能获得瞬间的显示时间。如果可能的话,我想设置少量的延迟,以至少提供MainPage一定的屏幕时间。

下面是我目前执行路由的代码。

    // MainPage, LoginPage, and HomePage are all StatefulWidgets.
    // AccessKeyStore is a singleton I use to handle all my access keys.
    // SlidingAnimationRoute is an extended CupertinoPageRoute

    @override
    void afterFirstLayout(BuildContext context) async {
        bool notFirstLogin = await AccessKeyStore().keyPairStored(AccessKeyStore().getLastActivePairNumber());
        var landingPage;

        if (notFirstLogin)
            landingPage = MainPage();
        else
            landingPage = LoginPage(title: 'Initial Login');

        Navigator.of(context).pop();
        Navigator.push(context, new SlidingAnimationRoute(builder: (context) => landingPage));
    }
Run Code Online (Sandbox Code Playgroud)

所以到目前为止,我已经做了以下工作,但我找不到任何可以满足我需要的所有设计选择的东西。

  • 导航到新页面时弹出MainPage(如上所示)。问题是按LoginPage或上的后退按钮HomePage上的后退按钮会显示纯黑屏幕,并且您必须再次按后退才能完全退出。
  • LoginPage使应用程序在按下和上的后退按钮后退出HomePage。但如前所述,当在启动应用程序之外的任何其他上下文中调用时,这都不好。
  • 使用 Android 和 iOS 启动画面。有效,但它几乎没有做出我需要的决策,应该将用户重定向到另一个页面。
  • 完全废弃启动屏幕并根据登录状态使其动态化MaterialApphome这不起作用,我最终得到了一个纯黑的屏幕,什么也没有启动。甚至不是HomePageLoginPage

所以我的主要问题是:如何在 Flutter 中(正确)实现启动屏幕,从而使下一页根据条件动态变化?(因为我可能忽略了 Flutter 的一些功能。)有没有办法在转换之前添加最短的时间,以便启动页面获得几秒钟的屏幕时间?

如果您需要一个示例,Twitter 应用程序始终显示启动屏幕,但可以重定向到主页(如果您已登录)或登录页面(如果您已注销)。我正在努力实现同样的目标。

Amp*_*nda 5

\n
    \n
  1. 后退按钮重定向到初始屏幕。当我按下 MainPage 或 LoginPage 上的后退按钮时,我会返回到初始屏幕。这很好,但我依靠 LoginPage 来登录多个帐户(因此,如果它们在任何其他上下文中启动,它们会在按下后退按钮 \xe2\x80\x93 时退出应用程序,这是你不想要的当您在设置屏幕中无害地添加新帐户时发生)
  2. \n
\n
\n\n

我真的不明白为什么弹出和推送不会影响它,而是使用它,您可以使用它Navigator.pushAndRemoveUntil()来导航SplashScreen

\n\n
Navigator.pushAndRemoveUntil(context, new SlidingAnimationRoute(builder: (context) => landingPage), (_) => false);\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后一个参数是RoutePredicate. 来自https://api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html

\n\n
\n

要删除推送的路由下面的所有路由,请使用始终返回 false 的 RoutePredicate(例如 (Route route) => false)。

\n
\n\n
\n\n
\n
    \n
  1. 屏幕只是冻结,直到构建下一个页面。当它运行时,我在屏幕上显示一个 CircularProgressIndicator,以向用户指示应用程序正在启动并且应该很快打开。这非常有帮助,因为如果我不添加它,用户可能会变得不耐烦并简单地转向另一个应用程序。问题是,通过调用 afterFirstLayout,页面在转到新页面之前只能获得瞬间的显示时间。如果可能的话,我想设置少量的延迟,至少给 MainPage 一些屏幕时间。
  2. \n
\n
\n\n

您可以使用延迟操作Future.delayed

\n\n
Future.delayed(Duration(seconds: 1), () {\n  Navigator.pushAndRemoveUntil(context, new SlidingAnimationRoute(builder: (context) => landingPage), (_) => false);\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

我看到你使用afterFirstLayoutpackage 来获取,context这很好,但实际上你可以通过简单地使用addPostFrameCallback内部来实现initState

\n\n
@override\nvoid initState() {\n  super.initState();\n\n  SchedulerBinding.instance.addPostFrameCallback((_) {\n    // you can use "context" here, for example:\n    Future.delayed(Duration(seconds: 1), () {\n      Navigator.pushAndRemoveUntil(context, new SlidingAnimationRoute(builder: (context) => landingPage), (_) => false);\n    });\n  })\n}\n
Run Code Online (Sandbox Code Playgroud)\n