一统天下 flutter - 路由和导航: 路由和导航的进阶
一统天下 flutter - 路由和导航: 路由和导航的进阶
示例如下:
lib\route\navigator2.dart
/*
* 路由和导航的进阶
*
* 主要请看 route_c.dart 中的说明
*/
import 'package:flutter/material.dart';
import 'package:flutter_demo/helper.dart';
import 'package:flutter_demo/route/route_a.dart';
import 'package:flutter_demo/route/route_b.dart';
import 'package:flutter_demo/route/route_c.dart';
import 'package:flutter_demo/route/route_d.dart';
class Navigator2Demo extends StatelessWidget {
const Navigator2Demo({super.key});
@override
Widget build(BuildContext context) {
/// 这里的 MaterialApp 是 main.dart 中的 MaterialApp 的子
return MaterialApp(
home: null,
/// 当 home 设置为 null 时,首次加载会自动导航至 initialRoute 指定的路由
initialRoute: '/',
/// 当 home 设置为 null 时,可以通过如下方式,在首次加载的时候 push 多个路由
/// 下面的运行结果为:首次加载时会显示 RouteBDemo,对 RouteBDemo 做 pop 后会显示 RouteADemo
/*
onGenerateInitialRoutes: (settings) {
return [
MaterialPageRoute(builder: (context){
return const RouteADemo();
}),
MaterialPageRoute(builder: (context){
return const RouteBDemo();
}),
];
},
*/
/// 一个 MaterialApp 中注册的路由表,在这个 MaterialApp 内的所有路由均可使用
routes:{
"/":(context) => const MyNavigator2Demo(title: '主页'),
"/route_a":(context) => const RouteADemo(),
"/route_b":(context) => const RouteBDemo(),
"/route_c":(context) => const RouteCDemo(),
"/route_d":(context) => const RouteDDemo(),
},
);
}
}
class MyNavigator2Demo extends StatefulWidget {
const MyNavigator2Demo({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyNavigator2DemoState createState() => _MyNavigator2DemoState();
}
class _MyNavigator2DemoState extends State<MyNavigator2Demo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Wrap(
spacing: 10,
children: [
MyButton(
onPressed: () {
Navigator.of(context).pushNamed('/route_a');
},
child: const Text('导航到 route a'),
),
],
),
);
}
}
lib\route\route_a.dart
import 'package:flutter/material.dart';
import '../helper.dart';
class RouteADemo extends StatelessWidget {
const RouteADemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('route a'),
),
body: Wrap(
spacing: 10,
children: [
MyButton(
onPressed: () {
Navigator.of(context).pushNamed('/route_b');
},
child: const Text('导航到 route b'),
),
],
),
);
}
}
lib\route\route_b.dart
import 'package:flutter/material.dart';
import '../helper.dart';
class RouteBDemo extends StatelessWidget {
const RouteBDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('route b'),
),
body: Wrap(
spacing: 10,
children: [
MyButton(
onPressed: () {
Navigator.of(context).pushNamed('/route_c');
},
child: const Text('导航到 route c'),
),
],
),
);
}
}
lib\route\route_c.dart
import 'package:flutter/material.dart';
import '../helper.dart';
class RouteCDemo extends StatelessWidget {
const RouteCDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('route c'),
),
body: Wrap(
spacing: 10,
children: [
MyButton(
onPressed: () {
/// 返回到顶级 MaterialApp 的根路由(即从路由堆栈中做 pop 直到显示根路由为止)
Navigator.of(context, rootNavigator:true).pop();
},
child: const Text('返回到根路由'),
),
MyButton(
onPressed: () {
/// pushReplacementNamed - 用指定的路由替换当前栈顶的路由(效果和 popAndPushNamed 差不多)
Navigator.of(context).pushReplacementNamed('/route_d');
},
child: const Text('导航到 route d(pushReplacementNamed)'),
),
MyButton(
onPressed: () {
/// popAndPushNamed - 将当前栈顶的路由 pop 掉,然后 push 指定的路由(效果和 pushReplacementNamed 差不多)
Navigator.of(context).popAndPushNamed('/route_d');
},
child: const Text('导航到 route d(popAndPushNamed)'),
),
MyButton(
onPressed: () {
/// popUntil - 在路由堆栈中做 pop 直到显示指定的路由
Navigator.of(context).popUntil(ModalRoute.withName('/'));
},
child: const Text('在路由堆栈中做 pop 直到显示指定的路由'),
),
MyButton(
onPressed: () {
/// push 到指定的路由,并在其下做 pop 直到指定的路由
/// 导航至 route_d,然后 route_d 下面的路由做 pop 直到 route_a,也就是说路由栈中 route_d 的下面是 route_a
Navigator.of(context).pushNamedAndRemoveUntil('/route_d', ModalRoute.withName('/route_a'));
},
child: const Text('在路由堆栈中做 pop 直到显示指定的路由,然后 push 指定的路由'),
),
],
),
);
}
}
lib\route\route_d.dart
import 'package:flutter/material.dart';
class RouteDDemo extends StatelessWidget {
const RouteDDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('route d'),
),
body:null,
);
}
}