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

Kya*_*Tun 5 page-lifecycle widget dart 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;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

凭证提供者界面

abstract CredentialProvider {
    void setCredential(Credential c);
}
Run Code Online (Sandbox Code Playgroud)

中的登录按钮侦听器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.
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

看来,我必须等待当前摘要循环完成才能调用Navigator.pushNamed(context, "/");。有没有什么好的方法可以像setTimeout在JavaScript中那样在抖动摘要循环中执行?

有点奇怪,是有条件的创造MaterialApp。颤动中是否有更好的图案?

Col*_*son 5

回答您的直接问题,addPostFrameCallback或者Future.delayed可以在最小延迟后调用代码。但是,此模式存在一些问题:

  • 我建议您只有一个MaterialApp小部件。您可以为登录页面设置单独的路由。
  • 在Flutter中,状态从父级流到子级。孩子不应在父对象上调用方法State。相反,父级可以将回调传递给子级。或者一个ChangeNotifier。如果没有其他方法可以执行所需的操作,则可以使用a 从应用程序中的任何位置GlobalKey访问AppComponentState并调用setCredential,但是这样做会丢失一些封装性和可测试性。
  • "/"如果用户按下“后退”按钮并返回到上一个位置,则在导航器堆栈上推动另一个可能会导致问题。您可能想要触发的是LoginPageand 的父部件的重建Desktop。或者,您可以runApp()再次致电以强制重建所有内容