颤动:状态改变后如何导航到新页面?

时间:2017-08-16 14:13:21

标签: widget dart page-lifecycle flutter

状态更改后如何导航到新页面?

我有一个需要先登录的应用。仅在登录后,才会完全创建应用程序组件。所以我写了这样的话:

主要应用

class AppComponentState extends State<AppComponent> implements CredentialProvider {

  Credential credential;

  @override
  Widget build(BuildContext context) {
    if (credential == null) {
      return new MaterialApp(
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => new LoginPage(this),
        },
      );
    } else {
      return new MaterialApp(
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => new Desktop(credential),
          ...
        },
      );
    }
  }
  @override
  void setCredential(Credential s) {
    setState(() {
      credential = s;
    });
  }
}

凭据提供程序接口

abstract CredentialProvider {
    void setCredential(Credential c);
}

LoginPage中的登录按钮侦听器,凭据已设置并路由到新页面。

@override
Widget build(BuildContext context) {

  void _handleSubmitted() {
    ...
    credentialProvider.setCredential(c); // this change main widget state and hence new pages are created
    // call setTimeout ?
    Navigator.pushNamed(context, "/"); // this should go to new page, because credential is set.
  }

  ...
}

看起来,我必须在调用Navigator.pushNamed(context, "/");之前等待当前digest loop完成。有没有什么好方法可以在javascript中像setTimeout这样的颤动摘要周期中做什么?

MaterialApp的条件创建有点奇怪。颤动有更好的模式吗?

1 个答案:

答案 0 :(得分:3)

要回答您的直接问题,addPostFrameCallbackFuture.delayed可以在最短延迟后调用代码。但是,这种模式存在一些问题:

  • 我建议您只有一个MaterialApp小部件。您可以为登录页面设置单独的路径。
  • 在Flutter中,州从父母流向儿童。儿童不应该在父State上调用方法。相反,父母可以将回调传递给孩子。或者是ChangeNotifier。如果没有其他方法可以执行您想要的操作,您可以使用GlobalKey从应用中的任何位置访问AppComponentState并在其上调用setCredential,但是你这样做会失去一些封装和可测试性。
  • 如果用户按下后退按钮并返回上一个位置,则在导航器堆栈上推送另一个"/"可能会导致问题。您可能想要的是触发重建某个窗口小部件,该窗口小部件是LoginPageDesktop的父级。或者,您可以再次致电runApp()以强制所有重建。