说明
路由,页面跳转是一个应用最基本功能之一。页面跳转包括2个基本问题,一是跳转时的参数传递;二是页面返回时参数回传。
跳转方式
flutter有2种跳转方式:1,直接push,pop;2,pushName,pop
直接push,pop
步骤:
- 创建两个路由;
- 用 Navigator.push() 跳转到第二个路由;
- 用 Navigator.pop() 回退到第一个路由
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondRoute()),
);
Navigator.pop(context);
pushName,pop
步骤:
- 创建两个界面
- 定义路由
- 使用
Navigator.pushNamed()
跳转到第二个界面- 使用
Navigator.pop()
返回到第一个界面
MaterialApp(
title: 'Named Routes Demo',
// 使用“/”命名路由来启动应用(Start the app with the "/" named route. In our case, the app will start)
// 在这里,应用将从 FirstScreen Widget 启动(on the FirstScreen Widget)
initialRoute: '/',
routes: {
'/': (context) => const FirstScreen(),
'/second': (context) => const SecondScreen(),
},
)
// 在 `FirstScreen` Widget中(Within the `FirstScreen` Widget)
onPressed: () {
// 使用命名路由跳转到第二个界面(Navigate to the second screen using a named route)
Navigator.pushNamed(context, '/second');
}
// 在 SecondScreen Widget 中(Within the SecondScreen Widget)
onPressed: () {
// 通过从堆栈弹出当前路由(Navigate back to the first screen by popping the current route)
// 来返回到第一个界面(off the stack)
Navigator.pop(context);
}
给特定的route传参
步骤:
1,定义需要传递的参数
2,创建组件来获取参数
3,把组件注册到路由表中
4,导航到组件
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
ExtractArgumentsScreen.routeName: (context) =>
const ExtractArgumentsScreen(),
}, //把组件注册到路由表中
onGenerateRoute: (settings) {
if (settings.name == PassArgumentsScreen.routeName) {
final args = settings.arguments as ScreenArguments;
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
},
title: 'Navigation with Arguments',
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 导航到组件
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'Extract Arguments Screen',
'This message is extracted in the build method.',
),
);
},
child: const Text('导航到提取参数的屏幕'),
),
ElevatedButton(
onPressed: () {
// 导航到组件
Navigator.pushNamed(
context,
PassArgumentsScreen.routeName,
arguments: ScreenArguments(
'Accept Arguments Screen',
'This message is extracted in the onGenerateRoute '
'function.',
),
);
},
child: const Text('导航到接受参数的命名'),
),
],
),
),
);
}
}
// 创建组件,从 `ScreenArguments` 提取 `title` 和 `message` 参数并展示。
//为了访问 `ScreenArguments`,可以使用 ModalRoute.of() 方法。这个方法返回的是当前路由及其携带的参数
class ExtractArgumentsScreen extends StatelessWidget {
const ExtractArgumentsScreen({super.key});
static const routeName = '/extractArguments';
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;
return Scaffold(
appBar: AppBar(
title: Text(args.title),
),
body: Center(
child: Text(args.message),
),
);
}
}
//使用 onGenerateRoute 提取参数
class PassArgumentsScreen extends StatelessWidget {
static const routeName = '/passArguments';
final String title;
final String message;
const PassArgumentsScreen({
super.key,
required this.title,
required this.message,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
);
}
}
// 定义需要传递的参数
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
从一个页面回传数据
步骤:
1,创建主屏界面
2,添加按钮,点击时跳转到选择界面
3,在选择界面显示两个按钮
4,当任意一个按钮被点击,关闭选择界面回退到主屏界面
5,在主屏界面显示 snackbar ,展示选中的项目
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}
//创建主屏界面
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
body: const Center(
child: SelectionButton(),
),
);
}
}
//添加按钮,点击时跳转到选择界面
class SelectionButton extends StatelessWidget {
const SelectionButton({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
//在主屏界面显示一个 snackbar,展示选中的项目
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
}
//在选择界面显示两个按钮
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, 'Yep!');
},
child: const Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, 'Nope.');
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}
传递数据到新页面
步骤:
1, 定义一个描述待办事项的数据类
2, 显示待办事项
3,创建一个显示待办事项详细信息的界面
4,传递数据并跳转到待办事项详细信息界面
import 'package:flutter/material.dart';
//定义一个描述待办事项的数据类
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
//创建待办事项列表
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}
//创建一个待办页面显示待办事件列表
class TodosScreen extends StatelessWidget {
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const 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 {
const DetailScreen({super.key, required this.todo});
final Todo todo;
@override
Widget build(BuildContext context) {
// 传递数据并跳转到待办事项详细信息界面
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
网友评论