Reputation: 4054
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('/'));
},
),
),
Upvotes: 25
Views: 27600
Reputation: 11
The simplest way is to add pageTransitionsTheme in your ThemeData, here is how you can achieve that behavior globally. Now every navigation you make will behave like an iOS transition
import 'package:flutter/material.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(
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.android: CupertinoPageTransitionsBuilder()
},
),
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
initialRoute: '/',
routes: {
'/p01' : (context) => p01(),
'/p02' : (context) => p02(),
'/p03' : (context) => p03(),
},
);
}
}
Upvotes: 0
Reputation: 9815
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 MaterialApp
and 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'),
),
],
),
);
}
}
Upvotes: 42