Navigator、路由传参、命名路由
1. 跳转到新页面
// 跳转到新页面
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
// 返回上一页
Navigator.pop(context);
2. 完整示例
// 首页
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('首页')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage()),
);
},
child: Text('跳转到详情页'),
),
),
);
}
}
// 详情页
class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('详情页')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('返回'),
),
),
);
}
}
1. 传递参数到新页面
// 传递参数
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
id: 123,
title: '商品详情',
),
),
);
// 接收参数
class DetailPage extends StatelessWidget {
final int id;
final String title;
const DetailPage({
Key? key,
required this.id,
required this.title,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(
child: Text('ID: $id'),
),
);
}
}
2. 返回数据到上一页
// 页面A:等待返回结果
class PageA extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('页面A')),
body: Center(
child: ElevatedButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => PageB()),
);
print('返回的结果: $result');
},
child: Text('跳转到页面B'),
),
),
);
}
}
// 页面B:返回数据
class PageB extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('页面B')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context, '选择了选项1');
},
child: Text('选项1'),
),
ElevatedButton(
onPressed: () {
Navigator.pop(context, '选择了选项2');
},
child: Text('选项2'),
),
],
),
),
);
}
}
1. 配置路由表
// main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter路由示例',
initialRoute: '/', // 初始路由
routes: {
'/': (context) => HomePage(),
'/detail': (context) => DetailPage(),
'/settings': (context) => SettingsPage(),
'/profile': (context) => ProfilePage(),
},
);
}
}
2. 使用命名路由导航
// 跳转到命名路由
Navigator.pushNamed(context, '/detail');
// 替换当前路由
Navigator.pushReplacementNamed(context, '/home');
// 清空路由栈并跳转
Navigator.pushNamedAndRemoveUntil(
context,
'/home',
(route) => false, // 移除所有路由
);
3. 命名路由传参
// 传递参数
Navigator.pushNamed(
context,
'/detail',
arguments: {
'id': 123,
'title': '商品详情',
},
);
// 接收参数
class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map;
final id = args['id'];
final title = args['title'];
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(child: Text('ID: $id')),
);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter路由',
onGenerateRoute: (settings) {
// 根据路由名称返回对应页面
if (settings.name == '/detail') {
final args = settings.arguments as Map;
return MaterialPageRoute(
builder: (context) => DetailPage(
id: args['id'],
title: args['title'],
),
);
}
// 未知路由
return MaterialPageRoute(
builder: (context) => NotFoundPage(),
);
},
);
}
}
// 自定义路由动画
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// 滑动动画
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.easeInOut;
var tween = Tween(begin: begin, end: end).chain(
CurveTween(curve: curve),
);
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
transitionDuration: Duration(milliseconds: 300),
),
);
// 淡入动画
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(
opacity: animation,
child: child,
);
},
),
);
// 缩放动画
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return ScaleTransition(
scale: animation,
child: child,
);
},
),
);
class MainPage extends StatefulWidget {
@override
State createState() => _MainPageState();
}
class _MainPageState extends State {
int _currentIndex = 0;
final List _pages = [
HomePage(),
CategoryPage(),
CartPage(),
ProfilePage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: '分类',
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: '购物车',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: '我的',
),
],
),
);
}
}
class TabBarPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('TabBar示例'),
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.home), text: '首页'),
Tab(icon: Icon(Icons.star), text: '收藏'),
Tab(icon: Icon(Icons.person), text: '我的'),
],
),
),
body: TabBarView(
children: [
Center(child: Text('首页内容')),
Center(child: Text('收藏内容')),
Center(child: Text('我的内容')),
],
),
),
);
}
}
Scaffold(
appBar: AppBar(title: Text('抽屉导航')),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 30,
backgroundImage: NetworkImage('https://example.com/avatar.jpg'),
),
SizedBox(height: 10),
Text(
'用户名',
style: TextStyle(color: Colors.white, fontSize: 18),
),
],
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('首页'),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, '/home');
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('设置'),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, '/settings');
},
),
Divider(),
ListTile(
leading: Icon(Icons.exit_to_app),
title: Text('退出'),
onTap: () {
// 退出逻辑
},
),
],
),
),
body: Center(child: Text('主页内容')),
)