How to navigate to new page after state change?
I had an app that require login first. Only after login, the app component are fully created. So I wrote something like this:
Main app
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;
});
}
}
Credential provider interface
abstract CredentialProvider {
void setCredential(Credential c);
}
The login button listener in LoginPage
, credential is set and route to the new page.
@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.
}
...
}
It seem like, I have to wait current digest loop to finish before invoking Navigator.pushNamed(context, "/");
. Is there any good way to do in flutter digest cycle like setTimeout
in javascript?
It is a bit weird, conditional creation of MaterialApp
. Is there better pattern in flutter?
To answer your direct question, addPostFrameCallback
or Future.delayed
can call code after a minimal delay. However, there are some issues with this pattern:
MaterialApp
widget. You can have a separate route for the login page.State
. Instead the parent can pass callbacks to the children. Or perhaps a ChangeNotifier
. If there's no other way to do what you want, you could use a GlobalKey
to get access to the AppComponentState
from any place in the app and call setCredential
on it, but you're losing some encapsulation and testability by doing so."/"
on the navigator stack might cause issues if the user presses the back button and goes back to the previous place. Probably what you want is to trigger a rebuild of some widget that is a parent of LoginPage
and Desktop
. Or you can call runApp()
again to force everything to rebuild.