导航到一个新页面和返回
Navigator.push方法
跳转后样子
import 'package:flutter/material.dart';
void main(){
runApp(MaterialApp(
title: '基本路由',
home: FirstRoute(),
));
}
class FirstRoute extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: (){
// Navigator.push跳转的页面自带返回键
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondRoute()));
}
),
),
);
}
}
class SecondRoute extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Second Route'),
),
body: Center(
child: RaisedButton(
child: Text('Go back'),
onPressed: (){
Navigator.pop(context);
}),
),
);
}
}
导航到一个新页面带参数返回
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: '带参数返回路由',
home: HomeScreen(),
));
}
//第一屏页面
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Returning with data'),
),
body: Center(
child: SelectionButton(),
),
);
}
}
class SelectionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RaisedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Text('Pick an option, any option!'),
);
}
_navigateAndDisplaySelection(BuildContext context) async {
//用result接受第二屏的返回值
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SelectionScreen()),
);
//级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量。 使用级联操作符可以避免创建 临时变量
Scaffold.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text("$result"),));
}
}
//第二屏页面
class SelectionScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
// 在这里返回 "Yep"
Navigator.pop(context,'Yep!');
},
child: Text('Yep'),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
// 在这里返回 "Noep"
Navigator.pop(context,'Noep!');
}, child: Text('Noep'),),
),
],
),
),
);
}
}
通过构造函数携带参数跳转
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() {
runApp(MaterialApp(
title: '携参数跳转',
home:TodosScreen(todos: List.generate(20, (i)=> Todo(
'Todo $i',
'A description of what needs to be done for Todo $i'
))),
));
}
// 数据类(要携带的数据)
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),));
},
);
}),
);
}
}
//构造函数接受传递过来的参数
class DetailScreen extends StatelessWidget{
final Todo todo;
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(padding: EdgeInsets.all(16.0),child: Text(todo.description),),
);
}
}
通过RoutSettings携带参数跳转
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() {
runApp(MaterialApp(
title: 'RouteSettings携参数跳转',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo('Todo $i',
'A description of what needs to be done for Todo $i'))),
));
}
// 数据类(要携带的数据)
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(),
//通过RouteSettings传递参数
settings: RouteSettings(
arguments: todos[index]
)
));
},
);
}),
);
}
}
//构造函数接受传递过来的参数
class DetailScreen extends StatelessWidget {
// DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
//通过ModalRoute取参数
final Todo todo = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
命名路由
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: '命名路由',
//当使用 initialRoute 时,需要确保你没有同时定义 home 属性
initialRoute: '/',
routes: {
// 当我们跳转到“/”时,构建 FirstScreen
'/':(context) => FirstScreen(),
// 当我们跳转到“/second”时,构建 SecondScreen
'/second':(context) =>SecondScreen(),
},
));
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
onPressed: () {
// 点击时跳转到第二个界面
Navigator.pushNamed(context, '/second');
},
child: Text('Launch screen'),),
),
);
}
}
class SecondScreen extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: RaisedButton(onPressed: (){
// 点击时跳转回第一个界面!
Navigator.pop(context);
},child: Text('Go back!'),),
),
);
}
}
给特定路由传参
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//通过 onGenerateRoute() 函数提取参数,然后把参数传递给组件,和routes是两种方式
onGenerateRoute: (settings) {
if (settings.name == PassArgumentsScreen.routeName) {
final ScreenArguments arguments = settings.arguments;
return MaterialPageRoute(builder: (context) {
return PassArgumentsScreen(
title: arguments.title,
message: arguments.message,
);
});
}
return null;
},
title: '给特定路由传参',
home: HomeScreen(),
routes: {
//把组件注册到路由表中
ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
},
);
}
}
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () {
Navigator.pushNamed(context, ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'秦时明月',
'沧海横流',
));
},
child: Text('Navigate to screen that extracts arguments'),
),
RaisedButton(
onPressed: () {
Navigator.pushNamed(context, PassArgumentsScreen.routeName,
arguments: ScreenArguments(
'九歌·少司命',
'悲莫悲兮生别离,乐莫乐兮新相知'
)
);
},
child: Text('Navigate to a named that accepts arguments'),
),
],
),
),
);
}
}
//ModalRoute接受参数
class ExtractArgumentsScreen extends StatelessWidget {
static const routeName = '/extractArguments';
@override
Widget build(BuildContext context) {
// ModalRoute.of() 方法返回的是当前路由及其携带的参数
final ScreenArguments arguments = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text(arguments.title),
),
body: Center(
child: Text(arguments.message),
),
);
}
}
//构造方法接受参数
class PassArgumentsScreen extends StatelessWidget {
static const routeName = '/passArguments';
final String title;
final String message;
PassArgumentsScreen({Key key, @required this.title, @required this.message})
: super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
);
}
}
转场动画路由Hero
import 'package:flutter/material.dart';
void main() => runApp(HeroAPP());
class HeroAPP extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'Transition Demo',
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
body: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return DetailScreen();
}));
},
child: Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
)),
);
}
}
class DetailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
),
),
),
);
}
}