I am trying to figure out good architectural solution for following problem: I have following First level routes that can also be referred to as layouts:
/onboarding/* -> Shows onboarding layout
/dashboard/* -> Shows dashboard layout
/overlay/* -> shows slide up overlay layout
/modal/* -> shows modal layout
User is routed to each of these depending on his/her auth state, actions etc.. I got this stage correctly.
Issues arise when I want to use Secondary level routes that can be referred to as pages, for example
/onboarding/signin -> Shows onboarding layout, that displays signin route
/onboarding/plan -> Shows onboarding layout, that displays plan options
/modal/plan-info -> Shows modal layout, over previous page (/onboarding/plan) and displays plan-information page.
How can I best define / organise these in a way where I can efficiently route to layouts and pages they display? Note, that whenever I route pages inside one layout, layout is not changing, but I want to animate content (pages) that are changing inside of it based on route.
Thus far I achieved following
import "package:flutter/widgets.dart";
import "package:skimitar/layouts/Onboarding.dart";
import "package:skimitar/layouts/Dashboard.dart";
Route generate(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/onboarding":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Onboarding();
});
break;
case "/dashboard":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Dashboard();
});
break;
}
return page;
}
/* Main */
void main() {
runApp(new WidgetsApp(
onGenerateRoute: generate, color: const Color(0xFFFFFFFFF)));
}
This routes to on boarding and dashboard layouts (right now just simple Containers wrapping text). I also believe that I can use PageRouteBuilder
latter on to animate transitions between routes? Now I need to figure out how to have something like nested secondary router inside on boarding and dashboard.
Below is somewhat of a visual representation of what I want to achieve, I need to be able to successfully route blue and red bits. In this example as long as we are under /dashboard
blue bit (layout) doesn't change, but as we navigate from say /dashboard/home
to /dashboard/stats
the red bit (page) should fade out and fade in with new content. If we navigate away from /dashboard/home
to say /onboarding/home
, the red bit (layout) should fade away, along with its currently active page and show new layout for onboarding and the story continues.
EDIT I made a bit of the progress with approach outlined below, essentially I will determine layout inside my runApp
and will declare new WidgetsApp
and routes inside each of the layouts. It seems to work, but there is an issue, When I click "SignUp" I am redirected to correct page, but I can also see old page below it.
main.dart
import "package:flutter/widgets.dart";
import "package:myProject/containers/layouts/Onboarding.dart";
/* Main */
void main() {
runApp(new Onboarding());
}
Onboarding.dart
import "package:flutter/widgets.dart";
import "package:myProject/containers/pages/SignIn.dart";
import "package:myProject/containers/pages/SignUp.dart";
import "package:myProject/services/helpers.dart";
/* Onboarding router */
Route onboardingRouter(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/":
page = buildOnboardingRoute(new SignIn());
break;
case "/sign-up":
page = buildOnboardingRoute(new SignUp());
break;
default:
page = buildOnboardingRoute(new SignIn());
}
return page;
}
class Onboarding extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF000000),
image: new DecorationImage(
image: new AssetImage("assets/images/background-fire.jpg"),
fit: BoxFit.cover)),
child: new WidgetsApp(
onGenerateRoute: onboardingRouter, color: const Color(0xFF000000)),
);
}
}
SignUp.dart
import "package:flutter/widgets.dart";
class SignUp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text("Sign Up",
style: new TextStyle(color: const Color(0xFFFFFFFF))));
}
}
helpers.dart
import "package:flutter/widgets.dart";
Route buildOnboardingRoute(Widget page) {
return new PageRouteBuilder(
opaque: true,
pageBuilder: (BuildContext context, _, __) {
return page;
});
}
See Question&Answers more detail:
os