navigator2的核心在在于自己维护页面的数组。
整体目录:
main.dart
import 'package:flutter/material.dart';
import 'mainpage/main_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
导航器 hello_navigator.dart
import 'package:demo3/page/rank_page.dart';
import 'package:flutter/material.dart';
enum RouteStatus { home, rank }
abstract class _RouteJumpListener {
void onJumpTo(RouteStatus routeStatus, {Map args});
}
typedef OnJumpTo = void Function(RouteStatus routeStatus, {Map? args});
///获取routeStatus在页面栈中的位置
int getPageIndex(List<MaterialPage> pages, RouteStatus routeStatus) {
for (int i = 0; i < pages.length; i++) {
MaterialPage page = pages[i];
if (getStatus(page) == routeStatus) {
return i;
}
}
return -1;
}
///获取page对应的RouteStatus
RouteStatus getStatus(MaterialPage page) {
if (page.child is RankPage) {
return RouteStatus.rank;
}
return RouteStatus.home;
}
class RouteJumpListener {
final OnJumpTo onJumpTo;
RouteJumpListener({required this.onJumpTo});
}
/// 导航工具类
class HelloNavigator extends _RouteJumpListener {
RouteJumpListener? routeJumpListener;
static HelloNavigator? _instance;
HelloNavigator._();
static HelloNavigator getInstance() {
if (_instance == null) {
_instance = HelloNavigator._();
}
return _instance!;
}
void registerRouteJump(RouteJumpListener listener) {
routeJumpListener = listener;
}
@override
void onJumpTo(RouteStatus routeStatus, {Map? args}) {
routeJumpListener?.onJumpTo(routeStatus, args: args);
}
}
mainpage.dart
import 'package:demo3/navigator/hello_navigator.dart';
import 'package:demo3/page/rank_page.dart';
import 'package:flutter/material.dart';
import '../page/home_page.dart';
pageWrap(Widget child) {
return MaterialPage(key: ValueKey(child.hashCode), child: child);
}
const MaterialColor white = const MaterialColor(
0xFFFFFFFF,
<int, Color>{
50: Color(0xFFFFFFFF),
100: Color(0xFFFFFFFF),
200: Color(0xFFFFFFFF),
300: Color(0xFFFFFFFF),
400: Color(0xFFFFFFFF),
500: Color(0xFFFFFFFF),
600: Color(0xFFFFFFFF),
700: Color(0xFFFFFFFF),
800: Color(0xFFFFFFFF),
900: Color(0xFFFFFFFF),
},
);
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
HelloRouteDelegate _helloRouteDelegate = HelloRouteDelegate();
@override
Widget build(BuildContext context) {
var widget = Router(routerDelegate: _helloRouteDelegate);
return MaterialApp(home: widget, theme: ThemeData(primarySwatch: white));
}
}
class HelloRouteDelegate extends RouterDelegate<MyRouterPath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<MyRouterPath> {
final GlobalKey<NavigatorState> navigatorKey;
HelloRouteDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
HelloNavigator.getInstance().registerRouteJump(
RouteJumpListener(onJumpTo: (RouteStatus routeStatus, {Map? args}) {
_routeStatus = routeStatus;
notifyListeners();
}));
}
List<MaterialPage> pages = [];
RouteStatus _routeStatus = RouteStatus.home;
@override
Widget build(BuildContext context) {
var index = getPageIndex(pages, routeStatus);
List<MaterialPage> tempPages = pages;
if (index != -1) {
tempPages = tempPages.sublist(0, index);
}
var page;
if (routeStatus == RouteStatus.rank) {
page = pageWrap(RankPage());
} else {
pages.clear();
page = pageWrap(HomePage());
}
tempPages = [...tempPages, page];
pages = tempPages;
print("pages length is " + pages.length.toString());
return WillPopScope(
onWillPop: () async =>
!(await navigatorKey.currentState?.maybePop() ?? false),
child: Navigator(
key: navigatorKey,
pages: pages,
onPopPage: (route, result) {
//执行返回操作
if (!route.didPop(result)) {
return false;
}
pages.removeLast();
return true;
}),
);
}
@override
Future<void> setNewRoutePath(MyRouterPath configuration) async {}
RouteStatus get routeStatus {
return _routeStatus;
}
}
class MyRouterPath {
final String location;
MyRouterPath.home() : location = "/";
MyRouterPath.rank() : location = "/rank";
}
home_page.dart
import 'package:flutter/material.dart';
import 'package:demo3/navigator/hello_navigator.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
alignment: Alignment.center,
child: Container(
color: Colors.green,
width: 300,
height: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"HomePage",
style: TextStyle(color: Colors.black, fontSize: 40),
),
MaterialButton(
onPressed: () => {
print("hello"),
HelloNavigator.getInstance().onJumpTo(RouteStatus.rank)
},
color: Colors.blue,
child: Text("点击我吧"),
)
],
),
),
);
}
}
rank_page.dart
import 'package:flutter/material.dart';
import '../navigator/hello_navigator.dart';
class RankPage extends StatefulWidget {
const RankPage({Key? key}) : super(key: key);
@override
State<RankPage> createState() => _RankPageState();
}
class _RankPageState extends State<RankPage> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
alignment: Alignment.center,
child: Container(
color: Colors.red,
width: 300,
height: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"RankPage",
style: TextStyle(color: Colors.black, fontSize: 40),
),
MaterialButton(
onPressed: () => {
print("hello RankPage"),
HelloNavigator.getInstance().onJumpTo(RouteStatus.home)
},
color: Colors.blue,
child: Text("点击我吧"),
)
],
),
),
);
}
}