how to use CupertinoPageRoute and named routes in flutter? - flutter

I want to use a CupertinoPageRoute instead of the Navigator.pushNamed
with a routes array in MaterialApp.
Navigator.pushNamed(context, p01.routeName); works fine. But I want to accomplish two items.
I want the navigation to be Cupertino Style in Android. Right To left, instead of Bottom to Top.
Navigation will go very deep, and I want to include a return button... like this. Navigator.popUntil(context,
ModalRoute.withName('/')); where I can return to specific locations
in the navigation Stack.
HOW can I use routes, namedRoutes
and
CupertinoPageRoute(builder: (context) => p02.routeName);
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'p01.dart';
import 'p02.dart';
import 'p03.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
initialRoute: '/',
// routes: {
// '/p01' : (context) => p01(),
// '/p02' : (context) => p02(),
// '/p03' : (context) => p03(),
// },
//***** . this is what I am trying to use for routes.
routes: <String, WidgetBuilder>{
p01.routeName: (BuildContext context) => new p01(title: "p01"),
p02.routeName: (BuildContext context) => new p02(title: "p02"),
p03.routeName: (BuildContext context) => new p03(title: "p03"),
},
);
}
}
...
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text(" cup P01"),
onPressed: () {
print("p01 was pressed");
//Navigator.pushNamed(context, p01.routeName);
// CupertinoPageRoute(builder: (context) => AA02Disclaimer()),
//CupertinoPageRoute(builder: (context) => p02());
// CupertinoPageRoute( p02.routeName );
// p02.routeName: (BuildContext context) => new p02(title: "p02"),
//**** . this is the code I am trying to make work...
CupertinoPageRoute(builder: (context) => p02.routeName);
},
),
),
=======
This is code to return to the root.
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text("/"),
onPressed: () {
print("/ was pressed");
// Navigator.pushNamed(context, p03.routeName);
Navigator.popUntil(context, ModalRoute.withName('/'));
},
),
),

TL;DR: Use onGenerate of MaterialApp / CupertinoApp to use custom routes. For example CupertinoPageRoute. If you are already using the Cupertino-Style consider using CupertinoApp, which automatically uses the CupertinoPageRoute.
I've split this answer in two solutions, one with the default MaterialAppand one with the CupertinoApp(using Cupertino-Style):
Keeping your style (MaterialApp):
If you want to keep the MaterialApp as your root widget you'll have to replace the routes attribute of your MaterialApp with an onGenerate implementation:
Original:
routes: {
'/': (_) => HomePage(),
'deeper': (_) => DeeperPage(),
}
Changed with onGenerate:
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return CupertinoPageRoute(
builder: (_) => HomePage(), settings: settings);
case 'deeper':
return CupertinoPageRoute(
builder: (_) => DeeperPage(), settings: settings);
}
}
Now onGenerate handles the routing manually and uses for each route an CupertinoPageRoute. This replaces the complete routes: {...} structure.
Quick standalone example:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return CupertinoPageRoute(
builder: (_) => HomePage(), settings: settings);
case 'deeper':
return CupertinoPageRoute(
builder: (_) => DeeperPage(), settings: settings);
}
},
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Material!'),
),
body: Center(
child: RaisedButton(
child: Text('Take me deeper!'),
onPressed: () => Navigator.pushNamed(context, 'deeper'),
),
),
);
}
}
class DeeperPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Material!'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
child: Text('Home :)'),
onPressed: () =>
Navigator.popUntil(context, ModalRoute.withName('/')),
),
RaisedButton(
child: Text('Deeper!'),
onPressed: () => Navigator.pushNamed(context, 'deeper'),
),
],
),
);
}
}
Cupterino Style (CupertinoApp):
If you want to use the Cupertino-Style anyway, I would suggest to use the CupertinoApp widget instead of the MaterialApp widget (like already suggested in a comment by #anmol.majhail).
Then the default chosen navigation will always use the CupertinoPageRoute.
Quick standalone example:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoApp(
routes: {
'/': (_) => HomePage(),
'deeper': (_) => DeeperPage(),
},
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('Take me deeper!'),
onPressed: () => Navigator.pushNamed(context, 'deeper'),
),
),
);
}
}
class DeeperPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CupertinoButton(
child: Text('Home :)'),
onPressed: () =>
Navigator.popUntil(context, ModalRoute.withName('/')),
),
CupertinoButton(
child: Text('Deeper!'),
onPressed: () => Navigator.pushNamed(context, 'deeper'),
),
],
),
);
}
}

Related

How to use pushNamed with Dismissible Widget and see background transparent first page

I want to use pushNamed from page 1 to page 2 and use Dismissible Widget to close page 2.
when pull down I got a black screen when close it.
I want to see page 1 when I pull down close page 2
I use this example
class FirstScreen extends StatelessWidget {
const FirstScreen({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('First Screen'),
),
body: Center(
child: ElevatedButton(
// Within the `FirstScreen` widget
onPressed: () {
// Navigate to the second screen using a named route.
Navigator.pushNamed(context, '/second');
},
child: const Text('Launch screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
const SecondScreen({super.key});
#override
Widget build(BuildContext context) {
return Dismissible(
key: UniqueKey(),
movementDuration: const Duration(milliseconds: 0),
resizeDuration: const Duration(milliseconds: 1),
onDismissed: (d) => Navigator.of(context).pop(),
direction: DismissDirection.down,
child: Scaffold(
appBar: AppBar(
title: const Text('Second Screen'),
),
body: Center(
child: ElevatedButton(
// Within the SecondScreen widget
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
Navigator.pop(context);
},
child: const Text('Go back!'),
),
),
),
);
}
}
if I use this one it works!! but I don't want use it
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) => const SecondScreen(),
));
void main() {
runApp(
MaterialApp(
title: 'Named Routes Demo',
initialRoute: '/',
routes: {
'/': (context) => const FirstScreen(),
'/second': (context) => const SecondScreen(), }, ),
);
}
Use MaterialApp.onGenerateRoute instead of MaterialApp.routes and use the PageRouteBuilder that works already.
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Named Routes Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
onGenerateRoute: (settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (context) => const FirstScreen());
case '/second':
return PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
const SecondScreen(),
);
}
},
);
}
}

flutter int got to zero

I have a screen with a one button and anotherone with a Container to show a number. I declared a variable in the StatlessWidget class. The button adds 1 to the variable , however after leaving the Class with the container und return to it, I noticed the widgets get updated and my variable loses its value. I have tried initializing it in initState() but it still loses it's value.
import 'package:flutter/material.dart';
import 'package:generator/route_generator.dart';
import 'package:generator/main.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/menu',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class Menu extends StatelessWidget {
int data = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/second', arguments: data);
},
child: Text('go to the second'),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
int data = 0;
void eins() {
data = data + 25;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.toString(),
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/second', arguments: data);
},
child: Text('go to the second'),
),
RaisedButton(
child: Text('25'),
onPressed: eins,
)
],
),
));
}
}
class SecondPage extends StatelessWidget {
int data = 0;
SecondPage({Key key, #required this.data}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.toString(),
style: TextStyle(fontSize: 20),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/first');
},
child: Text('go to the first'),
),
],
),
));
}
}
another class
import 'package:flutter/material.dart';
import 'package:generator/main.dart';
import './main.dart';
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case '/first':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/third':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/menu':
return MaterialPageRoute(
builder: (_) => Menu(),
);
case '/second':
// if (args is int) {
return MaterialPageRoute(
builder: (_) => SecondPage(
data: args,
),
);
//}
// return _errorRoute();
//default:
//return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(
title: Text('Error'),
),
body: Center(
child: Text('ERROR'),
),
);
});
}
}
The first thing that is weird about your program is that you want to preserve state, in your case a counter variable, but to do that, you select a StatelessWidget. At the very least you will need a StatefulWidget. It's in the name already.
That said, it's not that easy, you may want to look up the different approaches to state management in Flutter: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
To expand on what #nvoigt said, pick a state management solution instead of passing around arguments from page to page. This way you can keep your widgets stateless, which is preferred but not possible to do what you want to do without a state management solution.
Here's a quick way using GetX state management. This can be done using Provider, RiverPod, Bloc/Cubit...pick your poison.
Here's a new controller class with your data and logic.
class DataController extends GetxController {
int data = 0;
void eins() {
data += 25;
update();
}
}
Then a couple small changes to the rest of your good and you're good to go.
void main() {
Get.put(DataController()); // initializing your controller
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/menu',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class Menu extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/second');
},
child: Text('go to the second'),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final controller = Get.find<DataController>(); // finding controller
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GetBuilder<DataController>( // wrap your text in GetBuilder to display variabe
builder: (_) {
return Text(
controller.data.toString(), // accessing variable via controller
);
},
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/second');
},
child: Text('go to the second'),
),
RaisedButton(
child: Text('25'),
onPressed: () {
controller.eins(); // accessing function via controller
}),
],
),
));
}
}
class SecondPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final controller = Get.find<DataController>(); // finding same instance of controller on new page
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GetBuilder<DataController>(
builder: (_) {
return Text(
controller.data.toString(),
);
},
),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/first');
},
child: Text('go to the first'),
),
],
),
));
}
}
// no longer need to pass anything in your router below
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/first':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/third':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/menu':
return MaterialPageRoute(
builder: (_) => Menu(),
);
case '/second':
// if (args is int) {
return MaterialPageRoute(
builder: (_) => SecondPage(),
);
//}
// return _errorRoute();
//default:
//return _errorRoute();
}
}

How can i use flutter drawer menu in page routing?

i am new to flutter also coding.
what i want to do:
to add drawer menu to main.dart, it will return Scaffold for all pages in the menu.
in every page i want to use different Scaffold. (appbar & body)
i created pages, routes, drawer; but i couldn't add drawer to pages and also in the Builder(main.dart), i think i have some mistakes.
main.dart is like this:
import 'package:flutter/material.dart';
import 'package:letter_app/screens/user/postbox.dart';
import 'package:letter_app/screens/user/unread.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
int selectedMenuItem = 0;
final pageOptions = [
PostBox(),
Unread(),
];
Widget buildDrawer(BuildContext context) {
return Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(),
),
ListTile(
title: Text('Unread'),
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => new Unread()));
Navigator.pop(context);
},
),
ListTile(
title: Text('Post Box'),
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => new PostBox()));
Navigator.pop(context);
},
),
],
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'New App',
theme: ThemeData.dark(),
routes: <String, WidgetBuilder>{
'/screens/user/unread.dart': (BuildContext context) => Unread(),
'/screens/user/postbox.dart': (BuildContext context) => PostBox(),
},
home: Builder(
builder: (context) => Scaffold(
drawer: buildDrawer(context),
body: Container(child: pageOptions[selectedMenuItem]),
),
),
);
}
}
unread.dart is like this:
import 'package:flutter/material.dart';
class Unread extends StatefulWidget {
#override
_UnreadState createState() => _UnreadState();
}
class _UnreadState extends State<Unread> {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: ,
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Unread'),
),
);
}
}
Just define the buildDrawer widget in a seperate dart file, import the file. Then, just assign it to every Scaffold.

how to get listview button to go to random route onTap

I am trying to use solution from here
How make button which open random page in Flutter?
but instead of RaisedButton, do it with my Listview buttons.
Here's what I have so far after I added the RandomRouteGenerator from the other StackOverflow:
ListView(
children: const <Widget>[
Card(
child: ListTile(
leading: Text('🐔'),
title: Text('Chicken'),
onTap: () {
Navigator.of(context).pushNamed(
RouteGenerator.getRandomNameOfRoute());
},
),
),
//... more Cards that would become other listview items
Here's the errors:
Compiler message:
lib/main.dart:163:28: Error: Not a constant expression.
Navigator.of(context).pushNamed(
^^^^^^^
lib/main.dart:163:25: Error: Method invocation is not a constant expression.
Navigator.of(context).pushNamed(
^^
lib/main.dart:164:32: Error: Method invocation is not a constant expression.
RouteGenerator.getRandomNameOfRoute());
^^^^^^^^^^^^^^^^^^^^
lib/main.dart:163:37: Error: Method invocation is not a constant expression.
Navigator.of(context).pushNamed(
^^^^^^^^^
lib/main.dart:162:20: Error: Not a constant expression.
onTap: () {
^^
Thanks
You can copy paste run full code below
You can remove keyword const of children: const <Widget>[
code snippet
child: ListView(children: <Widget>[
Card(
working demo
full code
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Random pages',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: 'start_page',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class RouteGenerator {
static List<String> myRandomPages = ['first_page', 'second_page'];
static String getRandomNameOfRoute() {
return myRandomPages[Random().nextInt(myRandomPages.length)];
}
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case 'start_page':
return MaterialPageRoute(builder: (_) => StartPage());
case 'first_page':
return MaterialPageRoute(
builder: (_) =>
FirstPage()); // FirstPage - is just a Widget with your content
case 'second_page':
return MaterialPageRoute(
builder: (_) => SecondPage()); // Also custom Widget
//... other random or not pages
}
}
}
class StartPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Start page'),
),
body: Column(
children: [
Expanded(
child: ListView(children: <Widget>[
Card(
child: ListTile(
leading: Text('🐔'),
title: Text('Chicken'),
onTap: () {
Navigator.of(context)
.pushNamed(RouteGenerator.getRandomNameOfRoute());
},
),
),
]),
),
Center(
child: RaisedButton(
child: Text('Go to random page'),
onPressed: () => Navigator.of(context)
.pushNamed(RouteGenerator.getRandomNameOfRoute()),
),
),
],
));
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("First Page");
}
}
class SecondPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("Second Page");
}
}
Try removing the const before the on the ListView children.

Inherited widgets and navigator

I found some answers about this [here, here] but none of them completely answer my question.
I'm going to be using the package provider to describe my question because it greatly reduces the boilerplate code.
What I want to do is to inject a dependency when (and only when) a route is called. I can achieve that by doing something like this on onGenerateRoute:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Routes Demo',
initialRoute: '/',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => HomePage());
case '/firstPage':
return MaterialPageRoute(
builder: (_) => Provider(
builder: (_) => MyComplexClass(),
child: FirstPage(),
),
);
case '/secondPage':
return MaterialPageRoute(builder: (_) => SecondPage());
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('Route does not exists'),
),
),
);
}
});
}
}
class MyComplexClass {
String message = 'UUUH I am so complex';
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
child: Text('Go to first page'),
onPressed: () {
Navigator.pushNamed(context, '/firstPage');
}),
],
),
));
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final myComplexClass = Provider.of<MyComplexClass>(context);
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Center(
child: Text(myComplexClass.message),
),
RaisedButton(
child: Text('Go to second page'),
onPressed: () {
Navigator.pushNamed(context, '/secondPage');
},
)
],
),
),
);
}
}
class SecondPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final myComplexClass = Provider.of<MyComplexClass>(context);
return Scaffold(
body: Center(
child: Text(myComplexClass.message),
),
);
}
}
This works fine for '/firstPage', but as soon as I push another route from inside 'firstPage' the context is lost and I loose access to MyComplexClass, since the navigator stays at the top of the tree together with MaterialApp the next route will loose the context where MyComplexClass was injected, I cannot manage to find a elegant solution to this.
This is the navigator stack we end up with:
As we can see SecondPage is not a child of Provider, hence the problem.
I don't want to inject all dependencies I have all at once on top of MainApp, I want to inject them as they're needed.
I considered creating new navigators each time I need another "fold", but that seems to become really messy very quickly.
How do I solve this issue?
In the following examples, both the route / and /login can access Provider.of<int>, but the route /other can't.
There are two solutions:
A StatefulWidget combined with a Provider.value that wraps each route.
Example:
class Foo extends StatefulWidget {
#override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> {
int myState = 42;
#override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (_) => Provider.value(value: myState, child: Home()),
'/login': (_) => Provider.value(value: myState, child: Login()),
'/other': (_) => Other(),
},
);
}
}
A private placeholder type that wraps MaterialApp combined with ProxyProvider:
Example:
class _Scope<T> {
_Scope(this.value);
final T value;
}
// ...
Widget build(BuildContext context) {
Provider(
builder: (_) => _Scope(42),
child: MaterialApp(
routes: {
'/': (_) => ProxyProvider<_Scope<int>, int>(
builder: (_, scope, __) => scope.value, child: Home()),
'/login': (_) => ProxyProvider<_Scope<int>, int>(
builder: (_, scope, __) => scope.value, child: Login()),
'/other': (_) => Other(),
},
),
);
}