2

I am very new to Flutter but coming from an Angular background here. Say I want to build a BaseFrame for my app, and depending on the routing, I want to change the INSIDE of that BaseFrame. I don't understand how this would work?

In Angular it would be something like:

'/page-one': PageOne(),
'/page-two': PageTwo(), children: [
    '/part-1': Part1(),
    '/part-2': Part2(),
];

And in this case, if you navigate to /page-two/part-1 then it would load PageTwo(), and it would load Part1() wherever you specified <app-route></app-route> on PageTwo(). I don't understand how one would do this in Flutter because in Flutter it seems like you can only ever have a single flat route in your main.dart (in your MaterialApp builder)

The best thing I can think of is to have a variable on PageTwo(), and have a type of switch statement:

switch (subPage) {
   case '/part-1':
       return Part1();
   case '/part-2':
       return Part2();
}

But this seems like a crappy solution. You also now have the problem of fixing animations etc yourself (because the MaterialApp won't help you here automatically).

Here is something about this but this seems super complicated for a noob. Is this really the right/only way to do this: Nesting routes with flutter

Paul Kruger
  • 2,094
  • 7
  • 22
  • 49

2 Answers2

2

You can do something like that using this package qlevar_router

A full example of your case

import 'package:flutter/material.dart';
import 'package:qlevar_router/qlevar_router.dart';

void main() {
  runApp(MyApp());
}

class AppRoutes {
  final routes = <QRouteBase>[
    QRoute(
      path: '/page-one',
      page: (c) => PageOne(),
    ),
    QRoute(
        path: '/page-two',
        page: (c) => PageTwo(c),
        initRoute: '/part-1',
        children: [
          QRoute(
            path: '/part-1',
            page: (c) => Part1(),
          ),
          QRoute(
            path: '/part-2',
            page: (c) => Part2(),
          )
        ])
  ];
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: QR.router(AppRoutes().routes, initRoute: '/page-one'),
      routeInformationParser: QR.routeParser(),
    );
  }
}

class PageOne extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(children: [
          Text('This is page one'),
          TextButton(
              onPressed: () => QR.to('/page-two/part-1'),
              child: Text('To Part 1')),
          TextButton(
              onPressed: () => QR.to('/page-two/part-2'),
              child: Text('To Part 2')),
        ]),
      ),
    );
  }
}

class PageTwo extends StatelessWidget {
  final QRouteChild child;
  PageTwo(this.child);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(children: [
          Text('This is page one'),
          TextButton(onPressed: () => QR.back(), child: Text('Back')),
          TextButton(
              onPressed: () => QR.to('/page-two/part-1'),
              child: Text('To Part 1')),
          TextButton(
              onPressed: () => QR.to('/page-two/part-2'),
              child: Text('To Part 2')),
          SizedBox(
            width: 500,
            height: 500,
            child: child.childRouter,
          )
        ]),
      ),
    );
  }
}

class Part1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text('This is part 1'));
  }
}

class Part2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text('This is part 2'));
  }
}

Note that page-tow doesn't change at all when you navigate between the children part-1 and part-2

Schaban
  • 126
  • 1
  • 6
0

You could just use something like a TabBar/TabBarView to have other pages show up within the pages you're on. Which then you could give an integer as a parameter of your PageTwo class which you could use that integer to select which page you initially navigate to. This is a fairly straightforward way to do what I think you want but more limited since you won't have different navigators within each of those initial pages. Unless the Parts pages are meant to have their own navigation. If you want to have separate navigators for screens you can do this. That's how the CupertinoTabbedScaffold works (though with CupertinoApps). Which may be something to look into.

Adrian Murray
  • 2,170
  • 1
  • 13
  • 15