Flutter Navigator, Horizontal Transiation with PageRoutebuilder - flutter

I'm trying to force a horizontal Transiation in the Flutter Navigator Widget. Navigator uses the platform Default Transition from one screen to the next. In iOS, the transition is Right to left. Pops Left to Right. In Android it is Bottom to Top. I believe solution is to use a PageRouteBuilder, but no luck getting it to work. I marked the method with the Navigator Widget that I'd like to modify with a PageRouteBuilder to get desired Horizontal transition.
Code Snippet 2, is the Transition code I have been trying to make work with no luck.
This code works as default transition.
import 'package:flutter/material.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: {
'/Second': (context) => SecondScreen(),
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonMaterial02(),
new Text('NAV DEMO...',),
new Text('How do I get a Horizontal Transition in Android?',),
],
),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
//================================================================
//================================================================
Padding ButtonMaterial02() {
return Padding(
padding: const EdgeInsets.all(18.0),
child: new MaterialButton(
onPressed: MatButton02_onPress,
child: new Text("Material Button 02"),
padding: EdgeInsets.all(50.0),
minWidth: double.infinity,
color: Theme.of(context).primaryColor,
),
);
}
// add Horizontal code here
void MatButton02_onPress() {
print(" MaterialButton02 onPressed...");
Navigator.pushNamed(context, '/Second');
//*************************************************
//*************************************************
// HOW do I replace the Navigator above to use
// PageRouteBuilder so I can force ANDROID to
// Transition Right to Left instead of BottomToTop?
//*************************************************
//*************************************************
}
}
//================================================================
//================================================================
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
child: new Text("RETURN"),
onPressed: (){
Navigator.pop(context);
},
),
),
);
}
}
//================================================================
//================================================================
Code Snippet 2... transition code I have been trying to use.
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.0, 0.0),
).animate(secondaryAnimation),
child: child,
),
);
},
);
Navigator.of(context).push('Second');

You're interested in using the CupertinoPageRoute.
It animates from right to left, designed to imitate iOS's transition animation.
Following the example here, replace MaterialPageRoute references with CupertinoPageRoute and you'll be set!

Related

With Flutter, how to make a scrollable screen contain a widget that can expand or not depending on whether the soft keyboard is opened or closed?

I am a Flutter beginner and I am currently trying to implement a login screen which must satisfy to the following requirements:
first the screen is made of a widget containing the username and password text fields, that occupies all the screen
the sign in button is anchored at the bottom of the screen
when the soft keyboard is opened, the first widget is no longer expanded to take all the screen
when the soft keyboard is closed, the screen should look like as the one described in the 1st bullet point
the screen should be scrollable (when the soft keyboard is opened, if all the widgets don't fit in the remaining screen not hidden by the keyboard, I still want to scroll to access all the screen's content)
Here are wireframes that describe what I would like to achieve with Flutter:
state: soft keyboard closed
state: soft keyboard opened
Is this feasible with Flutter? Currently here is what I have attempted:
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isSoftKeyboardOpen;
#override
void initState() {
super.initState();
var keyboardVisibilityController = KeyboardVisibilityController();
_isSoftKeyboardOpen = keyboardVisibilityController.isVisible;
// Subscribe
keyboardVisibilityController.onChange.listen((bool visible) {
setState(() {
_isSoftKeyboardOpen = visible;
});
});
}
#override
Widget build(BuildContext context) {
var mAppBar = AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
);
return Scaffold(
appBar: mAppBar,
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
padding: EdgeInsets.only(left: 16, right: 16),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: LayoutBuilder(
builder: (containerContext, constraint) {
return Container(
height: MediaQuery.of(containerContext).size.height - mAppBar.preferredSize.height - MediaQuery.of(context).padding.top,
color: Colors.green,
child: Column(
children: <Widget> [
Expanded(
flex: _isSoftKeyboardOpen ? 0 : 1,
child: Column(
children: <Widget> [
TextFormField(
decoration: InputDecoration(
labelText: "Username",
),
),
TextFormField(
decoration: InputDecoration(
labelText: "Password",
),
)
],
),
),
ElevatedButton(onPressed: null, child: Text("Sign in")
),
],
),
);
}
),
)
);
},
)
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
As you can see when the soft keyboard opens, the screen scrolls but there is unnecessary space below the button (which is the last element of the screen). Is there a way for me to change the screen height dynamically in my code to achieve what I want? Or is there another way to implement the sign in screen which fulfills my requirements.
You can user the below widget to gain your requirements:
return KeyboardVisibilityBuilder(
builder: (context, child, isKeyboardVisible) {
if (isKeyboardVisible) {
// build layout for visible keyboard
} else {
// build layout for invisible keyboard
}
},
child: child, // this widget goes to the builder's child property. Made for better performance.
);
Hi #Jane you can achieve the desired output using the below code.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SIGN IN'),
),
body: LayoutBuilder(builder: (context, constraint) {
return ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(16),
children: [
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Container(
color: Colors.white,
height: constraint.maxHeight -
32, // -32 to remove vertical padding
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: "Username",
),
),
TextFormField(
decoration: InputDecoration(
labelText: "Password",
),
),
],
),
ElevatedButton(onPressed: null, child: Text("Sign in"))
],
),
),
),
],
);
}));
}
}
Also, try to use plugins only in dire situations when you can't achieve a particular task with flutter available resources.

How to make AnimatedSwitcher animate if parent widget is rebuilt in Flutter?

I am trying to implement a selectable ListTile. When ListTile is selected it's leading icon changes and its background color changes. I am trying to use AnimatedSwitcher to animate the transition when icons are changed. And it works (as long as I don't change background color of the list tile).
Changing the background color of the ListTile causes the animation to not work anymore. And I think I know why that is. When background color of the ListTile is changed, entire ListTile gets rebuilt. Which causes AnimatedSwitcher to also be rebuilt instead of transitioning between icons. Is there a way I can implement what I am trying to do. Here is my full code.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
// This widget is the root of your application.
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool change = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: SomeStatelessWidget(
AnimatedSwitcher(
duration: Duration(seconds: 2),
child: change
? CircleAvatar(
key: UniqueKey(),
child: Icon(Icons.check),
)
: CircleAvatar(
key: UniqueKey(),
child: Text("A"),
),
transitionBuilder: (child, animation) {
return RotationTransition(
turns: animation,
child: child,
);
},
),
change),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.swap_horiz),
onPressed: () {
setState(() {
change = !change;
});
},
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
));
}
}
class SomeStatelessWidget extends StatelessWidget {
final Widget child;
final bool changed;
SomeStatelessWidget(this.child, this.changed);
#override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(8.0),
decoration: changed
? BoxDecoration(
color: Theme.of(context).selectedRowColor,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
shape: BoxShape.rectangle)
: null,
child: ListTile(
leading: child,
title: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("This is an example"),
),
),
);
}
}

flutter, PageRouteBuilder, adding Horizontal Transition

The native navigation transition for iOS is RightToLeft. The Native Navigation transition for ANDROID is Bottom to Top. I would like to override the Native Navigation transition in Flutter to have the same RIght to Left transtion across iOS and ANDROID. To do this, I am trying to use PageRouteBuilder but no luck getting it to work. The first code block, I have a very basic screen that works... but natively. The second snippet includes the navigation transition code I am attempting to integrate.
The Code I am trying to fix.
import 'package:flutter/material.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'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//==============================================
// How would I force a horizontal transition?
mbNav001(context),
new Text(
'Screen 1',
),
],
),
),
);
}
}
//===================================================
Padding mbNav001(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(28.0),
child: new MaterialButton(
height: 80.0,
padding: EdgeInsets.all(50.0),
minWidth: double.infinity,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
child: new Text(
"material button a",
style: new TextStyle(
fontSize: 20.0,
color: Colors.yellow,
),
),
splashColor: Colors.redAccent,
// ----- This line is giving me error...
onPressed: () {
print('click mb');
//===========================================================
// How to force a horizontal trans in Navigation?
//===========================================================
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
}
// expecting to find... :
),
);
}
//===================================================
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to first screen when tapped!
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
this is the transition code I am trying to add.
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.0, 0.0),
).animate(secondaryAnimation),
child: child,
),
);
},
);
Navigator.of(context).push(pageRoute);
Using CupertinoPageRoute instead of MaterialPageRoute resolved the same issue in my case, without trying to apply any custom animation.
Navigator.of(context).push(CupertinoPageRoute(builder: (context) => MyPanel()));
This is the code i've used to achieve the slide up from the bottom animation on iOS. You'd just need to edit the tween values to achieve a left to right animation.
var builder = PageRouteBuilder(
pageBuilder: (BuildContext context,
Animation animation,
Animation secondaryAnimation) {
return YourChildWidgetHere();
},
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return new SlideTransition(
position: new Tween<Offset>(
begin: const Offset(0.0, 1.0),
end: Offset.zero,
).animate(animation),
child: child,
);
});
Navigator.of(context).push(builder);

flutter, adding a PageRouteBuilder

I am trying to modify my Navigation Transition code to use PageRouteBuilder. See method _gotoThirdPage().
The problem is that I cannot pass parameters to new Page. For example, I crash when passing title. Also looking for examples of sending multiple parameters, such as a map.
REQUEST: Could someone Modify the _gotoThirdPage() method to send parameters to Class SecondPage.
//====================. Code below ===================
import 'package:flutter/material.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'),
// Added ===
routes: <String, WidgetBuilder>{
SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
onPressed: _gotoSecondPage,
child: new Text("Goto SecondPage- Normal"),
),
new RaisedButton(onPressed: _gotoThirdPage,
child: new Text("goto SecondPage = with PRB"),
),
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _gotoSecondPage() {
//=========================================================
// Transition - Normal Platform Specific
print('==== going to second page ===');
print( SecondPage.routeName);
Navigator.pushNamed(context, SecondPage.routeName);
}
void _gotoThirdPage() {
//=========================================================
// I believe this is where I would be adding a PageRouteBuilder
print('==== going to second page ===');
print( SecondPage.routeName);
//Navigator.pushNamed(context, SecondPage.routeName);
//=========================================================
//=== please put PageRouteBuilderCode here.
final pageRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
// YOUR WIDGET CODE HERE
// I need to PASS title here...
// not sure how to do this.
// Also, is there a way to clean this code up?
return new SecondPage();
},
transitionsBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.0, 0.0),
).animate(secondaryAnimation),
child: child,
),
);
},
);
Navigator.of(context).push(pageRoute);
}
}
class SecondPage extends StatefulWidget {
SecondPage({Key key, this.title}) : super(key: key);
static const String routeName = "/SecondPage";
final String title;
#override
_SecondPageState createState() => new _SecondPageState();
}
/// // 1. After the page has been created, register it with the app routes
/// routes: <String, WidgetBuilder>{
/// SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
/// },
///
/// // 2. Then this could be used to navigate to the page.
/// Navigator.pushNamed(context, SecondPage.routeName);
///
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
//======== HOW TO PASS widget.title ===========
title: new Text(widget.title),
//title: new Text('==== second page ==='),
),
body: new Container(),
floatingActionButton: new FloatingActionButton(
onPressed: _onFloatingActionButtonPressed,
tooltip: 'Add',
child: new Icon(Icons.add),
),
);
}
void _onFloatingActionButtonPressed() {
}
}
I am not quite sure what you are trying to do. The easiest way to pass parameters to new Page for me is using the constructor of the new page if I need to do some processing- show/ use/ pass them later on. Although I dont think it is appropriate if you have large number of parameters.
So in some cases I would use SharedPrefences. I think this will be better for sending multiple parameters, such as a map.
Btw about your navigation I advise you to use Navigate with named routes. Something like:
MaterialApp(
// Start the app with the "/" named route. In our case, the app will start
// on the FirstScreen Widget
initialRoute: '/',
routes: {
// When we navigate to the "/" route, build the FirstScreen Widget
'/': (context) => FirstScreen(),
// When we navigate to the "/second" route, build the SecondScreen Widget
'/second': (context) => SecondScreen(),
},
);
And then:
Navigator.pushNamed(context, '/second');
Documentation.

Flutter, passing parameters to PageRoutebuilder

In Method gotoThirdScreen(), I am tryiing to pass parameters to a class.
I believe the issue starts at:
//=========================================================
//=== please put PageRouteBuilderCode here.
The Class SecondPage has... widget.title. But not sure how to pass titel from _gotoThirdPage().
This code works
//===============================
import 'package:flutter/material.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'),
// Added ===
routes: <String, WidgetBuilder>{
SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(28.0),
child: new RaisedButton(
onPressed: _gotoSecondPage,
child: new Text("Goto SecondPage- Normal"),
),
),
Padding(
padding: const EdgeInsets.all(38.0),
child: new RaisedButton(
onPressed: _gotoThirdPage,
child: new Text("goto SecondPage = with PRB"),
),
),
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _gotoSecondPage() {
//=========================================================
// Transition - Normal Platform Specific
print('==== going to second page ===');
print( SecondPage.routeName);
Navigator.pushNamed(context, SecondPage.routeName);
}
void _gotoThirdPage() {
//=========================================================
// I believe this is where I would be adding a PageRouteBuilder
print('==== going to second page ===');
print( SecondPage.routeName);
//Navigator.pushNamed(context, SecondPage.routeName);
//=========================================================
//=== please put PageRouteBuilderCode here.
final pageRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
// YOUR WIDGET CODE HERE
// I need to PASS title here...
// not sure how to do this.
// Also, is there a way to clean this code up?
return new SecondPage();
},
transitionsBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.0, 0.0),
).animate(secondaryAnimation),
child: child,
),
);
},
);
Navigator.of(context).push(pageRoute);
}
}
class SecondPage extends StatefulWidget {
SecondPage({Key key, this.title}) : super(key: key);
static const String routeName = "/SecondPage";
final String title;
#override
_SecondPageState createState() => new _SecondPageState();
}
/// // 1. After the page has been created, register it with the app routes
/// routes: <String, WidgetBuilder>{
/// SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
/// },
///
/// // 2. Then this could be used to navigate to the page.
/// Navigator.pushNamed(context, SecondPage.routeName);
///
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
//======== HOW TO PASS widget.title ===========
title: new Text(widget.title),
//title: new Text('==== second page ==='),
),
body: new Container(),
floatingActionButton: new FloatingActionButton(
onPressed: _onFloatingActionButtonPressed,
tooltip: 'Add',
child: new Icon(Icons.add),
),
);
}
void _onFloatingActionButtonPressed() {
}
}
you can use onGenerateRoute here the example
main.dart
void main() {
runApp(new App());
}
app.dart
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new HomeScreen(),
routes: <String, WidgetBuilder>{
'/home': (BuildContext context) => new HomeScreen(),
//other routes
},
//onGenerateRoute Custom
onGenerateRoute: getGenerateRoute);
}
}
Route<Null> getGenerateRoute(RouteSettings settings) {
final List<String> path = settings.name.split('/');
if (path[0] != '') return null;
if (path[1].startsWith('team')) {
if (path.length != 3) return null;
String _title = path[2];
return new MaterialPageRoute<Null>(
settings: settings,
builder: (BuildContext context) => new TeamScreen(
title: _title,
),
);
}
// The other paths we support are in the routes table.
return null;
}
home_screen.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Home Screen'),
),
body: new Center(
child: new Column(
children: <Widget>[
new RaisedButton(
onPressed: () {
String _title = "Team 1";
Navigator.pushNamed(context, '/team/$_title');
},
child: new Text('Go Team 1'),
),
new RaisedButton(
onPressed: () {
String _title = "Team 2";
Navigator.pushNamed(context, '/team/$_title');
},
child: new Text('Go Team 2'),
)
],
),
),
);
}
}
team.dart
import 'package:flutter/material.dart';
class TeamScreen extends StatelessWidget {
final String title;
const TeamScreen({Key key, this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Team screen'),
),
body: new Center(
child: new Text(title),
),
);
}
}
Pass title value to SecondPage constructor:
void _gotoThirdPage() {
String page_title = "Yet Another Page";
final pageRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
return new SecondPage(title: page_title);
},