13-04
This commit is contained in:
@@ -13,6 +13,7 @@ class PageA extends StatelessWidget {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('A 界面'),
|
title: const Text('A 界面'),
|
||||||
backgroundColor: bgColor,
|
backgroundColor: bgColor,
|
||||||
|
leading: BackButton(onPressed: _pop),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@@ -26,4 +27,7 @@ class PageA extends StatelessWidget {
|
|||||||
router.value = ['/', 'a', 'b'];
|
router.value = ['/', 'a', 'b'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pop() {
|
||||||
|
router.value = List.of(router.value)..removeLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ class PageC extends StatelessWidget {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('C 界面'),
|
title: const Text('C 界面'),
|
||||||
backgroundColor: bgColor,
|
backgroundColor: bgColor,
|
||||||
leading: BackButton(
|
leading: BackButton(onPressed: _pop),
|
||||||
onPressed: _pop,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Text('到达终点'),
|
child: Text('到达终点'),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import '../page_b.dart';
|
|||||||
import '../page_c.dart';
|
import '../page_c.dart';
|
||||||
import '../home_page.dart';
|
import '../home_page.dart';
|
||||||
|
|
||||||
class AppRouterDelegate extends RouterDelegate with ChangeNotifier{
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier{
|
||||||
|
|
||||||
List<String> _value = ['/'];
|
List<String> _value = ['/'];
|
||||||
|
|
||||||
@@ -35,13 +35,11 @@ class AppRouterDelegate extends RouterDelegate with ChangeNotifier{
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> popRoute() async{
|
Future<bool> popRoute() async{
|
||||||
print('================');
|
print('=======popRoute=========');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _onPopPage(Route route, result) {
|
bool _onPopPage(Route route, result) {
|
||||||
_value = List.of(_value)..removeLast();
|
|
||||||
notifyListeners();
|
|
||||||
return route.didPop(result);
|
return route.didPop(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class PageA extends StatelessWidget {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('A 界面'),
|
title: const Text('A 界面'),
|
||||||
backgroundColor: bgColor,
|
backgroundColor: bgColor,
|
||||||
|
leading: BackButton(onPressed: _pop),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@@ -26,4 +27,7 @@ class PageA extends StatelessWidget {
|
|||||||
router.value = ['/', 'a', 'b'];
|
router.value = ['/', 'a', 'b'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pop() {
|
||||||
|
router.value = List.of(router.value)..removeLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class PageB extends StatelessWidget {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('B 界面'),
|
title: const Text('B 界面'),
|
||||||
backgroundColor: bgColor,
|
backgroundColor: bgColor,
|
||||||
|
leading: BackButton(onPressed: _pop),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@@ -29,4 +29,7 @@ class PageB extends StatelessWidget {
|
|||||||
router.value = ['/','a','b','c'];
|
router.value = ['/','a','b','c'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pop() {
|
||||||
|
router.value = List.of(router.value)..removeLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,9 +14,14 @@ class PageC extends StatelessWidget {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('C 界面'),
|
title: const Text('C 界面'),
|
||||||
backgroundColor: bgColor,
|
backgroundColor: bgColor,
|
||||||
|
leading: BackButton(onPressed: _pop),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Text('到达终点'),
|
child: Text('到达终点'),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pop() {
|
||||||
|
router.value = List.of(router.value)..removeLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
lib/13/02/main.dart
Normal file
14
lib/13/02/main.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'pages/app/app.dart';
|
||||||
|
import 'pages/app/app_router_delegate.dart';
|
||||||
|
|
||||||
|
|
||||||
|
AppRouterDelegate router = AppRouterDelegate();
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const App());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
30
lib/13/02/pages/app/app.dart
Normal file
30
lib/13/02/pages/app/app.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../main.dart';
|
||||||
|
import 'app_tool_bar.dart';
|
||||||
|
|
||||||
|
class App extends StatelessWidget {
|
||||||
|
const App({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 0,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
))),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: const AppToolBar(),
|
||||||
|
body: Router(
|
||||||
|
routerDelegate: router,
|
||||||
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
93
lib/13/02/pages/app/app_router_delegate.dart
Normal file
93
lib/13/02/pages/app/app_router_delegate.dart
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../page_a.dart';
|
||||||
|
import '../page_b.dart';
|
||||||
|
import '../page_c.dart';
|
||||||
|
import '../home_page.dart';
|
||||||
|
|
||||||
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier{
|
||||||
|
|
||||||
|
List<String> _value = ['/'];
|
||||||
|
|
||||||
|
List<String> get value => _value;
|
||||||
|
|
||||||
|
set value(List<String> value){
|
||||||
|
_value = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Navigator(
|
||||||
|
onPopPage: _onPopPage,
|
||||||
|
pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Page> _pageMap = const {
|
||||||
|
'/': MaterialPage(child: HomePage()),
|
||||||
|
'a': MaterialPage(child: PageA()),
|
||||||
|
'b': MaterialPage(child: PageB()),
|
||||||
|
'c': MaterialPage(child: PageC()),
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> popRoute() async{
|
||||||
|
print('=======popRoute=========');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onPopPage(Route route, result) {
|
||||||
|
value = List.of(_value)..removeLast();
|
||||||
|
return route.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setNewRoutePath(configuration) async{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
|
||||||
|
//
|
||||||
|
// List<String> _value = ['/'];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> get value => _value;
|
||||||
|
//
|
||||||
|
// set value(List<String> value){
|
||||||
|
// _value = value;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Navigator(
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final Map<String, Page> _pageMap = const {
|
||||||
|
// '/': MaterialPage(child: HomePage()),
|
||||||
|
// 'a': MaterialPage(child: PageA()),
|
||||||
|
// 'b': MaterialPage(child: PageB()),
|
||||||
|
// 'c': MaterialPage(child: PageC()),
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// bool _onPopPage(Route route, result) {
|
||||||
|
// _value = List.of(_value)..removeLast();
|
||||||
|
// notifyListeners();
|
||||||
|
// return route.didPop(result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> setNewRoutePath(String configuration) async{
|
||||||
|
// }
|
||||||
|
// }
|
||||||
64
lib/13/02/pages/app/app_tool_bar.dart
Normal file
64
lib/13/02/pages/app/app_tool_bar.dart
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../main.dart';
|
||||||
|
|
||||||
|
class AppToolBar extends StatefulWidget implements PreferredSizeWidget{
|
||||||
|
const AppToolBar({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppToolBar> createState() => _AppToolBarState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppToolBarState extends State<AppToolBar> {
|
||||||
|
|
||||||
|
TextEditingController _ctrl = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_changRoute();
|
||||||
|
router.addListener(_changRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_changRoute);
|
||||||
|
_ctrl.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changRoute() {
|
||||||
|
_ctrl.text= router.value.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
elevation: 0,
|
||||||
|
title : TextField(
|
||||||
|
controller: _ctrl,
|
||||||
|
onSubmitted: _onSubmitted,
|
||||||
|
decoration: InputDecoration( //装饰
|
||||||
|
filled: true, //填充
|
||||||
|
fillColor: Color(0xffF3F6F9), //填充颜色
|
||||||
|
constraints: BoxConstraints(maxHeight: 34), //约束信息
|
||||||
|
contentPadding: EdgeInsets.only(top: -14,left: 10),
|
||||||
|
border: UnderlineInputBorder( //边线信息
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||||
|
),
|
||||||
|
hintText: "请输入路由", //提示字
|
||||||
|
hintStyle: TextStyle(fontSize: 14) //提示字样式
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSubmitted(String value) {
|
||||||
|
router.value = value.split(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/13/02/pages/home_page.dart
Normal file
30
lib/13/02/pages/home_page.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class HomePage extends StatelessWidget {
|
||||||
|
const HomePage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const Color bgColor = Color(0xffCCFFCC);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('主页起点'),
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
),
|
||||||
|
body: Center(child: ElevatedButton(
|
||||||
|
onPressed: () => toPageA(context),
|
||||||
|
child: const Text('Push A'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void toPageA(BuildContext context) {
|
||||||
|
router.value = ['/', 'a'];
|
||||||
|
}
|
||||||
|
}
|
||||||
29
lib/13/02/pages/page_a.dart
Normal file
29
lib/13/02/pages/page_a.dart
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
class PageA extends StatelessWidget {
|
||||||
|
const PageA({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const Color bgColor = Color(0xffCCFFFF);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('A 界面'),
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () => toPageB(context),
|
||||||
|
child: const Text('Push B'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void toPageB(BuildContext context) {
|
||||||
|
router.value = ['/', 'a', 'b'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
lib/13/02/pages/page_b.dart
Normal file
30
lib/13/02/pages/page_b.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
class PageB extends StatelessWidget {
|
||||||
|
const PageB({super.key});
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const Color bgColor = Color(0xffCCE5FF);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('B 界面'),
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () => toPageC(context),
|
||||||
|
child: const Text('Push C'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void toPageC(BuildContext context){
|
||||||
|
router.value = ['/','a','b','c'];
|
||||||
|
}
|
||||||
|
}
|
||||||
23
lib/13/02/pages/page_c.dart
Normal file
23
lib/13/02/pages/page_c.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
class PageC extends StatelessWidget {
|
||||||
|
const PageC({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const Color bgColor = Color(0xffFFE6CC);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('C 界面'),
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Text('到达终点'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
114
lib/13/03/app/navigation/app_router_delegate.dart
Normal file
114
lib/13/03/app/navigation/app_router_delegate.dart
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../pages/color/color_page.dart';
|
||||||
|
import '../../pages/empty/empty_page.dart';
|
||||||
|
import '../../pages/settings/settings_page.dart';
|
||||||
|
import '../../pages/counter/counter_page.dart';
|
||||||
|
import '../../pages/user/user_page.dart';
|
||||||
|
import '../../transition/fade_transition_page.dart';
|
||||||
|
import '../../transition/no_transition_page.dart';
|
||||||
|
|
||||||
|
const List<String> kDestinationsPaths = [
|
||||||
|
'/color',
|
||||||
|
'/counter',
|
||||||
|
'/user',
|
||||||
|
'/settings',
|
||||||
|
];
|
||||||
|
|
||||||
|
AppRouterDelegate router = AppRouterDelegate();
|
||||||
|
|
||||||
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier {
|
||||||
|
String _path = '/color';
|
||||||
|
|
||||||
|
String get path => _path;
|
||||||
|
|
||||||
|
set path(String value) {
|
||||||
|
if (_path == value) return;
|
||||||
|
_path = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Navigator(
|
||||||
|
onPopPage: _onPopPage,
|
||||||
|
pages: _buildPageByPath(path),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> _buildPageByPath(String path) {
|
||||||
|
Widget? child;
|
||||||
|
if (path == kDestinationsPaths[0]) {
|
||||||
|
child = const ColorPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[1]) {
|
||||||
|
child = const CounterPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[2]) {
|
||||||
|
child = const UserPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[3]) {
|
||||||
|
child = const SettingPage();
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
FadeTransitionPage(
|
||||||
|
key: ValueKey(path),
|
||||||
|
child: child ?? const EmptyPage(),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> popRoute() async {
|
||||||
|
print('=======popRoute=========');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onPopPage(Route route, result) {
|
||||||
|
return route.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setNewRoutePath(configuration) async {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
|
||||||
|
//
|
||||||
|
// List<String> _value = ['/'];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> get value => _value;
|
||||||
|
//
|
||||||
|
// set value(List<String> value){
|
||||||
|
// _value = value;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Navigator(
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final Map<String, Page> _pageMap = const {
|
||||||
|
// '/': MaterialPage(child: HomePage()),
|
||||||
|
// 'a': MaterialPage(child: PageA()),
|
||||||
|
// 'b': MaterialPage(child: PageB()),
|
||||||
|
// 'c': MaterialPage(child: PageC()),
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// bool _onPopPage(Route route, result) {
|
||||||
|
// _value = List.of(_value)..removeLast();
|
||||||
|
// notifyListeners();
|
||||||
|
// return route.didPop(result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> setNewRoutePath(String configuration) async{
|
||||||
|
// }
|
||||||
|
// }
|
||||||
53
lib/13/03/app/navigation/views/app_navigation_rail.dart
Normal file
53
lib/13/03/app/navigation/views/app_navigation_rail.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppNavigationRail extends StatefulWidget {
|
||||||
|
const AppNavigationRail({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppNavigationRail> createState() => _AppNavigationRailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppNavigationRailState extends State<AppNavigationRail> {
|
||||||
|
final List<NavigationRailDestination> destinations = const [
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.color_lens_outlined), label: Text("颜色板")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.add_chart), label: Text("计数器")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.person), label: Text("我的")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.settings), label: Text("设置")),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
router.addListener(_onRouterChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_onRouterChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
int _index = 0 ;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return NavigationRail(
|
||||||
|
labelType: NavigationRailLabelType.all,
|
||||||
|
onDestinationSelected: _onDestinationSelected,
|
||||||
|
destinations: destinations,
|
||||||
|
selectedIndex: _index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDestinationSelected(int index) {
|
||||||
|
router.path = kDestinationsPaths[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouterChange() {
|
||||||
|
_index = kDestinationsPaths.indexOf(router.path);
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
38
lib/13/03/app/unit_app.dart
Normal file
38
lib/13/03/app/unit_app.dart
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'navigation/app_router_delegate.dart';
|
||||||
|
import 'navigation/views/app_navigation_rail.dart';
|
||||||
|
|
||||||
|
class UnitApp extends StatelessWidget {
|
||||||
|
const UnitApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 0,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
))),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: Scaffold(
|
||||||
|
body: Row(
|
||||||
|
children: [
|
||||||
|
const AppNavigationRail(),
|
||||||
|
Expanded(
|
||||||
|
child: Router(
|
||||||
|
routerDelegate: router,
|
||||||
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'pages/app/app.dart';
|
import 'app/unit_app.dart';
|
||||||
|
import 'app/navigation/app_router_delegate.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const App());
|
runApp(const UnitApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
52
lib/13/03/pages/color/color_page.dart
Normal file
52
lib/13/03/pages/color/color_page.dart
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/common/components/colors_panel.dart';
|
||||||
|
import 'package:iroute/common/pages/stl_color_page.dart';
|
||||||
|
|
||||||
|
// class HomePage extends StatelessWidget {
|
||||||
|
// const HomePage({super.key});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Scaffold(
|
||||||
|
// body: const Center(child: Text('HomePage')));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class ColorPage extends StatefulWidget {
|
||||||
|
const ColorPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorPage> createState() => _ColorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorPageState extends State<ColorPage> {
|
||||||
|
final List<Color> _colors = [
|
||||||
|
Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange,
|
||||||
|
Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan,
|
||||||
|
Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent,
|
||||||
|
Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent,
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(title:const Text('颜色主页')),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _toAddPage,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
body: ColorsPanel(
|
||||||
|
colors: _colors,
|
||||||
|
onSelect: _selectColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor(Color color){
|
||||||
|
// String value = color.value.toRadixString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toAddPage() async {
|
||||||
|
}
|
||||||
|
}
|
||||||
43
lib/13/03/pages/counter/counter_page.dart
Normal file
43
lib/13/03/pages/counter/counter_page.dart
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CounterPage extends StatefulWidget {
|
||||||
|
const CounterPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CounterPage> createState() => _CounterPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CounterPageState extends State<CounterPage> {
|
||||||
|
int _counter = 0;
|
||||||
|
|
||||||
|
void _incrementCounter() {
|
||||||
|
setState(() {
|
||||||
|
_counter++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const Text(
|
||||||
|
'You have pushed the button this many times:',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'$_counter',
|
||||||
|
style: Theme.of(context).textTheme.headlineMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _incrementCounter,
|
||||||
|
tooltip: 'Increment',
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/13/03/pages/empty/empty_page.dart
Normal file
30
lib/13/03/pages/empty/empty_page.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EmptyPage extends StatelessWidget {
|
||||||
|
const EmptyPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('界面走丢了'),
|
||||||
|
),
|
||||||
|
body: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
direction: Axis.vertical,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.nearby_error,size: 64, color: Colors.grey),
|
||||||
|
Text(
|
||||||
|
'404 界面丢失',
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/13/03/pages/settings/settings_page.dart
Normal file
11
lib/13/03/pages/settings/settings_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingPage extends StatelessWidget {
|
||||||
|
const SettingPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('SettingPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/13/03/pages/user/user_page.dart
Normal file
11
lib/13/03/pages/user/user_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class UserPage extends StatelessWidget {
|
||||||
|
const UserPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('UserPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
53
lib/13/03/transition/fade_transition_page.dart
Normal file
53
lib/13/03/transition/fade_transition_page.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FadeTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
const FadeTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
this.duration = const Duration(milliseconds: 300),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) =>
|
||||||
|
PageBasedFadeTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageBasedFadeTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
final FadeTransitionPage<T> _page;
|
||||||
|
|
||||||
|
PageBasedFadeTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => _page.duration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
var curveTween = CurveTween(curve: Curves.easeIn);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation.drive(curveTween),
|
||||||
|
child: (settings as FadeTransitionPage).child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
47
lib/13/03/transition/no_transition_page.dart
Normal file
47
lib/13/03/transition/no_transition_page.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NoTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const NoTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) => NoTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
|
||||||
|
final NoTransitionPage<T> _page;
|
||||||
|
|
||||||
|
NoTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
return (settings as NoTransitionPage).child;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
13
lib/13/03_/main.dart
Normal file
13
lib/13/03_/main.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'pages/app/app.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const App());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
179
lib/13/04/app/navigation/app_router_delegate.dart
Normal file
179
lib/13/04/app/navigation/app_router_delegate.dart
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/13/04/app/navigation/router/iroute.dart';
|
||||||
|
|
||||||
|
import '../../pages/color/color_page.dart';
|
||||||
|
import '../../pages/empty/empty_page.dart';
|
||||||
|
import '../../pages/settings/settings_page.dart';
|
||||||
|
import '../../pages/counter/counter_page.dart';
|
||||||
|
import '../../pages/user/user_page.dart';
|
||||||
|
import '../../transition/fade_transition_page.dart';
|
||||||
|
import '../../pages/color/color_add_page.dart';
|
||||||
|
|
||||||
|
const List<String> kDestinationsPaths = [
|
||||||
|
'/color',
|
||||||
|
'/counter',
|
||||||
|
'/user',
|
||||||
|
'/settings',
|
||||||
|
];
|
||||||
|
|
||||||
|
AppRouterDelegate router = AppRouterDelegate();
|
||||||
|
|
||||||
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier {
|
||||||
|
String _path = '/color';
|
||||||
|
|
||||||
|
String get path => _path;
|
||||||
|
|
||||||
|
int? get activeIndex {
|
||||||
|
if(path.startsWith('/color')) return 0;
|
||||||
|
if(path.startsWith('/counter')) return 1;
|
||||||
|
if(path.startsWith('/user')) return 2;
|
||||||
|
if(path.startsWith('/settings')) return 3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
late Completer<dynamic> completer;
|
||||||
|
Future<dynamic> changePathForResult(String value) async{
|
||||||
|
completer = Completer();
|
||||||
|
path = value;
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
set path(String value) {
|
||||||
|
if (_path == value) return;
|
||||||
|
_path = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRoute? parserPath(String path){
|
||||||
|
//
|
||||||
|
// List<String> parts = path.split('/');
|
||||||
|
// String lever1 = '/${parts[1]}';
|
||||||
|
// List<IRoute> iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList();
|
||||||
|
//
|
||||||
|
// int counter = 2;
|
||||||
|
//
|
||||||
|
// IRoute? result;
|
||||||
|
// String check = lever1;
|
||||||
|
// for(int i = 0;i<iRoutes.length;i++){
|
||||||
|
// check = check +"/" + parts[counter];
|
||||||
|
// String path = iRoutes[i].path;
|
||||||
|
// if(path == check){
|
||||||
|
// result = iRoutes[i];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// // String path =
|
||||||
|
// // result.children.add(IRoute(path: parts[i]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Navigator(
|
||||||
|
onPopPage: _onPopPage,
|
||||||
|
pages: _buildPageByPath(path),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> _buildPageByPath(String path) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Widget? child;
|
||||||
|
List<Page> result = [];
|
||||||
|
if(path.startsWith('/color')){
|
||||||
|
result.add( FadeTransitionPage(
|
||||||
|
key: ValueKey('/color'),
|
||||||
|
child:const ColorPage(),
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
if(path == '/color/add'){
|
||||||
|
result.add( FadeTransitionPage(
|
||||||
|
key: ValueKey('/color/add'),
|
||||||
|
child:const ColorAddPage(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path == kDestinationsPaths[0]) {
|
||||||
|
child = const ColorPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[1]) {
|
||||||
|
child = const CounterPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[2]) {
|
||||||
|
child = const UserPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[3]) {
|
||||||
|
child = const SettingPage();
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
FadeTransitionPage(
|
||||||
|
// key: ValueKey(path),
|
||||||
|
child: child ?? const EmptyPage(),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> popRoute() async {
|
||||||
|
print('=======popRoute=========');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onPopPage(Route route, result) {
|
||||||
|
if(path == '/color/add'){
|
||||||
|
completer.complete(result);
|
||||||
|
path = '/color';
|
||||||
|
}
|
||||||
|
return route.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setNewRoutePath(configuration) async {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
|
||||||
|
//
|
||||||
|
// List<String> _value = ['/'];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> get value => _value;
|
||||||
|
//
|
||||||
|
// set value(List<String> value){
|
||||||
|
// _value = value;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Navigator(
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final Map<String, Page> _pageMap = const {
|
||||||
|
// '/': MaterialPage(child: HomePage()),
|
||||||
|
// 'a': MaterialPage(child: PageA()),
|
||||||
|
// 'b': MaterialPage(child: PageB()),
|
||||||
|
// 'c': MaterialPage(child: PageC()),
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// bool _onPopPage(Route route, result) {
|
||||||
|
// _value = List.of(_value)..removeLast();
|
||||||
|
// notifyListeners();
|
||||||
|
// return route.didPop(result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> setNewRoutePath(String configuration) async{
|
||||||
|
// }
|
||||||
|
// }
|
||||||
37
lib/13/04/app/navigation/router/iroute.dart
Normal file
37
lib/13/04/app/navigation/router/iroute.dart
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class IRoute {
|
||||||
|
final String path;
|
||||||
|
final List<IRoute> children;
|
||||||
|
|
||||||
|
const IRoute({required this.path, this.children = const []});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IRoute{path: $path, children: $children}';
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> list(){
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const List<IRoute> kDestinationsIRoutes = [
|
||||||
|
IRoute(
|
||||||
|
path: '/color',
|
||||||
|
children: [
|
||||||
|
IRoute(path: '/color/add'),
|
||||||
|
IRoute(path: '/color/detail'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/counter',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/user',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/settings',
|
||||||
|
),
|
||||||
|
];
|
||||||
50
lib/13/04/app/navigation/views/app_navigation_rail.dart
Normal file
50
lib/13/04/app/navigation/views/app_navigation_rail.dart
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppNavigationRail extends StatefulWidget {
|
||||||
|
const AppNavigationRail({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppNavigationRail> createState() => _AppNavigationRailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppNavigationRailState extends State<AppNavigationRail> {
|
||||||
|
final List<NavigationRailDestination> destinations = const [
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.color_lens_outlined), label: Text("颜色板")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.add_chart), label: Text("计数器")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.person), label: Text("我的")),
|
||||||
|
NavigationRailDestination(icon: Icon(Icons.settings), label: Text("设置")),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
router.addListener(_onRouterChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_onRouterChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return NavigationRail(
|
||||||
|
labelType: NavigationRailLabelType.all,
|
||||||
|
onDestinationSelected: _onDestinationSelected,
|
||||||
|
destinations: destinations,
|
||||||
|
selectedIndex: router.activeIndex,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDestinationSelected(int index) {
|
||||||
|
router.path = kDestinationsPaths[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouterChange() {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
38
lib/13/04/app/unit_app.dart
Normal file
38
lib/13/04/app/unit_app.dart
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'navigation/app_router_delegate.dart';
|
||||||
|
import 'navigation/views/app_navigation_rail.dart';
|
||||||
|
|
||||||
|
class UnitApp extends StatelessWidget {
|
||||||
|
const UnitApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 0,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
))),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: Scaffold(
|
||||||
|
body: Row(
|
||||||
|
children: [
|
||||||
|
const AppNavigationRail(),
|
||||||
|
Expanded(
|
||||||
|
child: Router(
|
||||||
|
routerDelegate: router,
|
||||||
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
16
lib/13/04/main.dart
Normal file
16
lib/13/04/main.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'app/unit_app.dart';
|
||||||
|
import 'app/navigation/app_router_delegate.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const UnitApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
67
lib/13/04/pages/color/color_add_page.dart
Normal file
67
lib/13/04/pages/color/color_add_page.dart
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ColorAddPage extends StatefulWidget {
|
||||||
|
const ColorAddPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorAddPage> createState() => _ColorAddPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorAddPageState extends State<ColorAddPage> {
|
||||||
|
late Color _color;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_color = randomColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String text = '# ${_color.value.toRadixString(16)}';
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(
|
||||||
|
// title: Text('添加颜色'),
|
||||||
|
// actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
|
||||||
|
// ),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 10),
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: Icon(
|
||||||
|
Icons.sell_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _color,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Random _random = Random();
|
||||||
|
|
||||||
|
Color get randomColor {
|
||||||
|
return Color.fromARGB(
|
||||||
|
255,
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor() {
|
||||||
|
Navigator.of(context).pop(_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
lib/13/04/pages/color/color_page.dart
Normal file
59
lib/13/04/pages/color/color_page.dart
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/common/components/colors_panel.dart';
|
||||||
|
import 'package:iroute/common/pages/stl_color_page.dart';
|
||||||
|
import '../../app/navigation/app_router_delegate.dart';
|
||||||
|
|
||||||
|
// class HomePage extends StatelessWidget {
|
||||||
|
// const HomePage({super.key});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Scaffold(
|
||||||
|
// body: const Center(child: Text('HomePage')));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class ColorPage extends StatefulWidget {
|
||||||
|
const ColorPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorPage> createState() => _ColorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorPageState extends State<ColorPage> {
|
||||||
|
final List<Color> _colors = [
|
||||||
|
Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange,
|
||||||
|
Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan,
|
||||||
|
Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent,
|
||||||
|
Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent,
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(title:const Text('颜色主页')),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _toAddPage,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
body: ColorsPanel(
|
||||||
|
colors: _colors,
|
||||||
|
onSelect: _selectColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor(Color color){
|
||||||
|
// String value = color.value.toRadixString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toAddPage() async {
|
||||||
|
dynamic color = await router.changePathForResult('/color/add');
|
||||||
|
if (color != null) {
|
||||||
|
setState(() {
|
||||||
|
_colors.add(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
lib/13/04/pages/counter/counter_page.dart
Normal file
43
lib/13/04/pages/counter/counter_page.dart
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CounterPage extends StatefulWidget {
|
||||||
|
const CounterPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CounterPage> createState() => _CounterPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CounterPageState extends State<CounterPage> {
|
||||||
|
int _counter = 0;
|
||||||
|
|
||||||
|
void _incrementCounter() {
|
||||||
|
setState(() {
|
||||||
|
_counter++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const Text(
|
||||||
|
'You have pushed the button this many times:',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'$_counter',
|
||||||
|
style: Theme.of(context).textTheme.headlineMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _incrementCounter,
|
||||||
|
tooltip: 'Increment',
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/13/04/pages/empty/empty_page.dart
Normal file
30
lib/13/04/pages/empty/empty_page.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EmptyPage extends StatelessWidget {
|
||||||
|
const EmptyPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('界面走丢了'),
|
||||||
|
),
|
||||||
|
body: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
direction: Axis.vertical,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.nearby_error,size: 64, color: Colors.grey),
|
||||||
|
Text(
|
||||||
|
'404 界面丢失',
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/13/04/pages/settings/settings_page.dart
Normal file
11
lib/13/04/pages/settings/settings_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingPage extends StatelessWidget {
|
||||||
|
const SettingPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('SettingPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/13/04/pages/user/user_page.dart
Normal file
11
lib/13/04/pages/user/user_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class UserPage extends StatelessWidget {
|
||||||
|
const UserPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('UserPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
53
lib/13/04/transition/fade_transition_page.dart
Normal file
53
lib/13/04/transition/fade_transition_page.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FadeTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
const FadeTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
this.duration = const Duration(milliseconds: 300),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) =>
|
||||||
|
PageBasedFadeTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageBasedFadeTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
final FadeTransitionPage<T> _page;
|
||||||
|
|
||||||
|
PageBasedFadeTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => _page.duration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
var curveTween = CurveTween(curve: Curves.easeIn);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation.drive(curveTween),
|
||||||
|
child: (settings as FadeTransitionPage).child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
47
lib/13/04/transition/no_transition_page.dart
Normal file
47
lib/13/04/transition/no_transition_page.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NoTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const NoTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) => NoTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
|
||||||
|
final NoTransitionPage<T> _page;
|
||||||
|
|
||||||
|
NoTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
return (settings as NoTransitionPage).child;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
6
lib/13/节点介绍.txt
Normal file
6
lib/13/节点介绍.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
01: Router#RouterDelegate 基础使用
|
||||||
|
改造基于数据控制 A、B、C 三个界面跳转。
|
||||||
|
|
||||||
|
02: 导航 2.0 中返回操作介绍
|
||||||
|
|
||||||
|
03: 侧栏菜单导航 V1
|
||||||
46
test/parser/main.dart
Normal file
46
test/parser/main.dart
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import 'package:iroute/13/04/app/navigation/router/iroute.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
String path = '/color/detail/a';
|
||||||
|
// List<String> parts = path.split('/');
|
||||||
|
// print(parts);
|
||||||
|
// print(parserPath(path));
|
||||||
|
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
print(uri.fragment);
|
||||||
|
print(uri.pathSegments);
|
||||||
|
|
||||||
|
List<String> parts = uri.pathSegments;
|
||||||
|
|
||||||
|
parts = List.of(parts)..removeLast();
|
||||||
|
String result = parts.join('/');
|
||||||
|
print(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IRoute? parserPath(String path){
|
||||||
|
|
||||||
|
List<String> parts = path.split('/');
|
||||||
|
String lever1 = '/${parts[1]}';
|
||||||
|
List<IRoute> iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList();
|
||||||
|
|
||||||
|
int counter = 2;
|
||||||
|
|
||||||
|
IRoute? result;
|
||||||
|
String check = lever1;
|
||||||
|
List<IRoute> children = iRoutes.first.children;
|
||||||
|
|
||||||
|
check = check +"/" + parts[counter];
|
||||||
|
|
||||||
|
for(int i = 0;i<children.length;i++){
|
||||||
|
|
||||||
|
String path = children[i].path;
|
||||||
|
if(path == check){
|
||||||
|
result = children[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// String path =
|
||||||
|
// result.children.add(IRoute(path: parts[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user