diff --git a/lib/13/01/main.dart b/lib/13/01/main.dart index 75b32c0..dc14a42 100644 --- a/lib/13/01/main.dart +++ b/lib/13/01/main.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:url_strategy/url_strategy.dart'; - -import 'pages/app.dart'; +import 'pages/app/app.dart'; +import 'pages/app/app_router_delegate.dart'; +AppRouterDelegate router = AppRouterDelegate(); void main() { - setHashUrlStrategy(); runApp(const App()); } diff --git a/lib/13/01/pages/app/app.dart b/lib/13/01/pages/app/app.dart new file mode 100644 index 0000000..2652869 --- /dev/null +++ b/lib/13/01/pages/app/app.dart @@ -0,0 +1,29 @@ +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), + )); + } +} + diff --git a/lib/13/01/pages/app/app_router_delegate.dart b/lib/13/01/pages/app/app_router_delegate.dart new file mode 100644 index 0000000..e6ffd43 --- /dev/null +++ b/lib/13/01/pages/app/app_router_delegate.dart @@ -0,0 +1,94 @@ +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 with ChangeNotifier{ + + List _value = ['/']; + + List get value => _value; + + set value(List value){ + _value = value; + notifyListeners(); + } + + @override + Widget build(BuildContext context) { + return Navigator( + onPopPage: _onPopPage, + pages: _value.map((e) => _pageMap[e]!).toList(), + ); + } + + final Map _pageMap = const { + '/': MaterialPage(child: HomePage()), + 'a': MaterialPage(child: PageA()), + 'b': MaterialPage(child: PageB()), + 'c': MaterialPage(child: PageC()), + }; + + @override + Future popRoute() async{ + print('================'); + return true; + } + + bool _onPopPage(Route route, result) { + _value = List.of(_value)..removeLast(); + notifyListeners(); + return route.didPop(result); + } + + @override + Future setNewRoutePath(configuration) async{ + + } + +} + +// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { +// +// List _value = ['/']; +// +// +// List get value => _value; +// +// set value(List value){ +// _value = value; +// notifyListeners(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Navigator( +// onPopPage: _onPopPage, +// pages: _value.map((e) => _pageMap[e]!).toList(), +// ); +// } +// +// final Map _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? navigatorKey = GlobalKey(); +// +// @override +// Future setNewRoutePath(String configuration) async{ +// } +// } \ No newline at end of file diff --git a/lib/13/01/pages/app/app_tool_bar.dart b/lib/13/01/pages/app/app_tool_bar.dart new file mode 100644 index 0000000..dc6eff8 --- /dev/null +++ b/lib/13/01/pages/app/app_tool_bar.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import '../../main.dart'; + +class AppToolBar extends StatefulWidget implements PreferredSizeWidget{ + const AppToolBar({super.key}); + + @override + State createState() => _AppToolBarState(); + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} + +class _AppToolBarState extends State { + + 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(','); + } +} diff --git a/lib/13/01/pages/home_page.dart b/lib/13/01/pages/home_page.dart index 47b4dc9..0c19d8d 100644 --- a/lib/13/01/pages/home_page.dart +++ b/lib/13/01/pages/home_page.dart @@ -1,46 +1,30 @@ + import 'package:flutter/material.dart'; -import '../route/route_state.dart'; -import 'color_add_page.dart'; -import '../../../common/components/colors_panel.dart'; -import '../../../common/pages/stl_color_page.dart'; +import '../main.dart'; -class HomePage extends StatefulWidget { + +class HomePage extends StatelessWidget { const HomePage({super.key}); - @override - State createState() => _HomePageState(); -} - -class _HomePageState extends State { - final List _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) { + const Color bgColor = Color(0xffCCFFCC); + return Scaffold( - appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), + backgroundColor: bgColor, + appBar: AppBar( + title: const Text('主页起点'), + backgroundColor: bgColor, + ), + body: Center(child: ElevatedButton( + onPressed: () => toPageA(context), + child: const Text('Push A'), ), - body: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ); + )); } - void _selectColor(Color color){ - String value = '#${color.value.toRadixString(16)}'; - RouteStateScope.of(context).go('/color/detail/$value'); - } - - void _toAddPage() async { - RouteStateScope.of(context).go('/color/add'); + void toPageA(BuildContext context) { + router.value = ['/', 'a']; } } diff --git a/lib/13/01/pages/page_a.dart b/lib/13/01/pages/page_a.dart new file mode 100644 index 0000000..6e454bc --- /dev/null +++ b/lib/13/01/pages/page_a.dart @@ -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']; + } + +} diff --git a/lib/13/01/pages/page_b.dart b/lib/13/01/pages/page_b.dart new file mode 100644 index 0000000..3366c2a --- /dev/null +++ b/lib/13/01/pages/page_b.dart @@ -0,0 +1,32 @@ +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']; + } + +} \ No newline at end of file diff --git a/lib/13/01/pages/page_c.dart b/lib/13/01/pages/page_c.dart new file mode 100644 index 0000000..b912861 --- /dev/null +++ b/lib/13/01/pages/page_c.dart @@ -0,0 +1,22 @@ +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('到达终点'), + )); + } +} diff --git a/lib/13/02/main.dart b/lib/13/01_/main.dart similarity index 100% rename from lib/13/02/main.dart rename to lib/13/01_/main.dart diff --git a/lib/13/01/pages/app.dart b/lib/13/01_/pages/app.dart similarity index 100% rename from lib/13/01/pages/app.dart rename to lib/13/01_/pages/app.dart diff --git a/lib/13/01/pages/color_add_page.dart b/lib/13/01_/pages/color_add_page.dart similarity index 100% rename from lib/13/01/pages/color_add_page.dart rename to lib/13/01_/pages/color_add_page.dart diff --git a/lib/13/01_/pages/home_page.dart b/lib/13/01_/pages/home_page.dart new file mode 100644 index 0000000..47b4dc9 --- /dev/null +++ b/lib/13/01_/pages/home_page.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import '../route/route_state.dart'; +import 'color_add_page.dart'; + +import '../../../common/components/colors_panel.dart'; +import '../../../common/pages/stl_color_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final List _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)}'; + RouteStateScope.of(context).go('/color/detail/$value'); + } + + void _toAddPage() async { + RouteStateScope.of(context).go('/color/add'); + } +} diff --git a/lib/13/01/route/parsed_route.dart b/lib/13/01_/route/parsed_route.dart similarity index 100% rename from lib/13/01/route/parsed_route.dart rename to lib/13/01_/route/parsed_route.dart diff --git a/lib/13/01/route/parser.dart b/lib/13/01_/route/parser.dart similarity index 100% rename from lib/13/01/route/parser.dart rename to lib/13/01_/route/parser.dart diff --git a/lib/13/01/route/route_state.dart b/lib/13/01_/route/route_state.dart similarity index 100% rename from lib/13/01/route/route_state.dart rename to lib/13/01_/route/route_state.dart diff --git a/lib/13/01__/main.dart b/lib/13/01__/main.dart new file mode 100644 index 0000000..75b32c0 --- /dev/null +++ b/lib/13/01__/main.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:url_strategy/url_strategy.dart'; + +import 'pages/app.dart'; + + + +void main() { + setHashUrlStrategy(); + runApp(const App()); +} + + + + diff --git a/lib/13/01__/pages/app.dart b/lib/13/01__/pages/app.dart new file mode 100644 index 0000000..11ff90f --- /dev/null +++ b/lib/13/01__/pages/app.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import '../route/parser.dart'; +import '../route/route_state.dart'; + +class App extends StatefulWidget { + const App({super.key}); + + @override + State createState() => _AppState(); +} + +class _AppState extends State { + late final RootRouterDelegate _delegate; + late final AppRouteParser _parser; + late final RouteState _routeState; + + @override + void initState() { + super.initState(); + _parser = AppRouteParser(); + _routeState = RouteState(_parser,initial: '/color'); + _delegate = RootRouterDelegate(_routeState); + } + + @override + Widget build(BuildContext context) { + return RouteStateScope( + notifier: _routeState, + child: MaterialApp.router( + routerDelegate: _delegate, + routeInformationParser: _parser, + theme: ThemeData( + useMaterial3: true, + appBarTheme: const AppBarTheme( + elevation: 0, + iconTheme: IconThemeData(color: Colors.black), + titleTextStyle: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ))), + debugShowCheckedModeBanner: false, + ), + ); + } +} diff --git a/lib/13/02/pages/color_add_page.dart b/lib/13/01__/pages/color_add_page.dart similarity index 100% rename from lib/13/02/pages/color_add_page.dart rename to lib/13/01__/pages/color_add_page.dart diff --git a/lib/13/01__/pages/home_page.dart b/lib/13/01__/pages/home_page.dart new file mode 100644 index 0000000..b5b949c --- /dev/null +++ b/lib/13/01__/pages/home_page.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import '../route/route_state.dart'; +import 'color_add_page.dart'; + +import '../../../common/components/colors_panel.dart'; +import '../../../common/pages/stl_color_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final List _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); + RouteStateScope.of(context).go('/color/detail?color=$value'); + } + + void _toAddPage() async { + RouteStateScope.of(context).go('/color/add'); + } +} diff --git a/lib/13/01__/route/parsed_route.dart b/lib/13/01__/route/parsed_route.dart new file mode 100644 index 0000000..f2bfb70 --- /dev/null +++ b/lib/13/01__/route/parsed_route.dart @@ -0,0 +1,21 @@ +// 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:collection/collection.dart'; +import 'package:equatable/equatable.dart'; +import 'package:quiver/core.dart'; + +/// A route path that has been parsed by [TemplateRouteParser]. +class ParsedRoute extends Equatable{ + /// The current path location without query parameters. (/book/123) + final String path; + + /// The query parameters ({search: abc}) + final Map queryParameters; + + const ParsedRoute(this.path, this.queryParameters); + + @override + List get props => [path,queryParameters]; +} diff --git a/lib/13/01__/route/parser.dart b/lib/13/01__/route/parser.dart new file mode 100644 index 0000000..0244de3 --- /dev/null +++ b/lib/13/01__/route/parser.dart @@ -0,0 +1,119 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:iroute/common/pages/stl_color_page.dart'; +import 'package:path_to_regexp/path_to_regexp.dart'; +import '../pages/home_page.dart'; +import '../pages/color_add_page.dart'; +import 'parsed_route.dart'; +import 'route_state.dart'; + +class AppRouteParser extends RouteInformationParser { + + @override + Future parseRouteInformation( + RouteInformation routeInformation) async { + print("=======parseRouteInformation:${routeInformation.uri.path}==================="); + + final uri = routeInformation.uri; + final path = uri.toString(); + final queryParams = uri.queryParameters; + + return ParsedRoute(path, queryParams); + } + + @override + RouteInformation? restoreRouteInformation(ParsedRoute configuration) { + print("=======restoreRouteInformation:${configuration}==================="); + + return RouteInformation(uri: Uri.parse(configuration.path)); + } +} + +class RootRouterDelegate extends RouterDelegate + with ChangeNotifier, PopNavigatorRouterDelegateMixin { + + final RouteState routeState; + + + RootRouterDelegate(this.routeState) { + routeState.addListener(notifyListeners); + } + + @override + final GlobalKey navigatorKey = GlobalKey(); + + @override + ParsedRoute get currentConfiguration { + print("=======currentConfiguration:${routeState.route.path}==================="); + + return routeState.route; + } + + @override + void dispose() { + routeState.removeListener(notifyListeners); + routeState.dispose(); + super.dispose(); + } + + final _addColorKey = const ValueKey('addColor'); + + @override + Widget build(BuildContext context) { + final routeState = RouteStateScope.of(context); + List pages =[]; + final String path = routeState.route.path; + + pages.add(MaterialPage(child: HomePage())); + + String? selectedColor; + if (path.startsWith('/color/detail') ) { + selectedColor = routeState.route.queryParameters['color']; + } + + if(selectedColor!=null){ + pages.add(MaterialPage(child: StlColorPage( + color: Color(int.parse(selectedColor,radix: 16)), + ))); + } + + bool isAddPage = path == '/color/add'; + if(isAddPage){ + pages.add(MaterialPage( + key: _addColorKey, + child: ColorAddPage())); + } + + return Navigator( + key: navigatorKey, + pages: pages, + onPopPage: (route, result) { + if (route.settings is Page && (route.settings as Page).key == _addColorKey) { + routeState.go('/color'); + } + + if(selectedColor!=null){ + selectedColor = null; + routeState.go('/color'); + } + + return route.didPop(result); + }, + ); + } + + /// 格式: /a /b + + @override + Future setNewRoutePath(ParsedRoute configuration) async { + print("===setNewRoutePath===${configuration}================="); + routeState.route = configuration; + return; + } + +// @override +// Future setInitialRoutePath( configuration) async{ +// _pages = [_pageMap['/']!]; +// notifyListeners(); +// } +} diff --git a/lib/13/01__/route/route_state.dart b/lib/13/01__/route/route_state.dart new file mode 100644 index 0000000..d21a397 --- /dev/null +++ b/lib/13/01__/route/route_state.dart @@ -0,0 +1,48 @@ +// 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/widgets.dart'; + +import 'parsed_route.dart'; +import 'parser.dart'; + +/// The current route state. To change the current route, call obtain the state +/// using `RouteStateScope.of(context)` and call `go()`: +/// +/// ``` +/// RouteStateScope.of(context).go('/book/2'); +/// ``` +class RouteState extends ChangeNotifier { + final AppRouteParser _parser; + ParsedRoute _route; + + RouteState(this._parser,{String initial=''}) : _route = ParsedRoute(initial,{}); + + ParsedRoute get route => _route; + + set route(ParsedRoute route) { + // Don't notify listeners if the path hasn't changed. + if (_route == route) return; + + _route = route; + notifyListeners(); + } + + Future go(String route) async { + this.route = await _parser + .parseRouteInformation(RouteInformation(uri: Uri.parse(route))); + } +} + +/// Provides the current [RouteState] to descendant widgets in the tree. +class RouteStateScope extends InheritedNotifier { + const RouteStateScope({ + required super.notifier, + required super.child, + super.key, + }); + + static RouteState of(BuildContext context) => + context.dependOnInheritedWidgetOfExactType()!.notifier!; +} diff --git a/lib/13/01___/main.dart b/lib/13/01___/main.dart new file mode 100644 index 0000000..75b32c0 --- /dev/null +++ b/lib/13/01___/main.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:url_strategy/url_strategy.dart'; + +import 'pages/app.dart'; + + + +void main() { + setHashUrlStrategy(); + runApp(const App()); +} + + + + diff --git a/lib/13/01___/pages/app.dart b/lib/13/01___/pages/app.dart new file mode 100644 index 0000000..c2013fe --- /dev/null +++ b/lib/13/01___/pages/app.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import '../route/parser.dart'; +import '../route/route_state.dart'; + +class App extends StatefulWidget { + const App({super.key}); + + @override + State createState() => _AppState(); +} + +AppRouteParser parser = AppRouteParser(); +AppRouterDelegate routerDelegate = AppRouterDelegate(); + +class _AppState extends State { + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + routerDelegate: routerDelegate, + routeInformationParser: parser, + // backButtonDispatcher: RootBackButtonDispatcher(), + theme: ThemeData( + useMaterial3: true, + appBarTheme: const AppBarTheme( + elevation: 0, + iconTheme: IconThemeData(color: Colors.black), + titleTextStyle: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ))), + debugShowCheckedModeBanner: false, + ); + } +} diff --git a/lib/13/01___/pages/color_add_page.dart b/lib/13/01___/pages/color_add_page.dart new file mode 100644 index 0000000..bee43b4 --- /dev/null +++ b/lib/13/01___/pages/color_add_page.dart @@ -0,0 +1,67 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class ColorAddPage extends StatefulWidget { + const ColorAddPage({super.key}); + + @override + State createState() => _ColorAddPageState(); +} + +class _ColorAddPageState extends State { + 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); + } +} diff --git a/lib/13/01___/pages/home_page.dart b/lib/13/01___/pages/home_page.dart new file mode 100644 index 0000000..54decfb --- /dev/null +++ b/lib/13/01___/pages/home_page.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import '../route/route_state.dart'; +import 'app.dart'; +import 'color_add_page.dart'; + +import '../../../common/components/colors_panel.dart'; +import '../../../common/pages/stl_color_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final List _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); + routerDelegate.go('/color/detail?color=$value'); + } + + void _toAddPage() async { + routerDelegate.go('/color/add'); + } +} diff --git a/lib/13/01___/route/parsed_route.dart b/lib/13/01___/route/parsed_route.dart new file mode 100644 index 0000000..f2bfb70 --- /dev/null +++ b/lib/13/01___/route/parsed_route.dart @@ -0,0 +1,21 @@ +// 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:collection/collection.dart'; +import 'package:equatable/equatable.dart'; +import 'package:quiver/core.dart'; + +/// A route path that has been parsed by [TemplateRouteParser]. +class ParsedRoute extends Equatable{ + /// The current path location without query parameters. (/book/123) + final String path; + + /// The query parameters ({search: abc}) + final Map queryParameters; + + const ParsedRoute(this.path, this.queryParameters); + + @override + List get props => [path,queryParameters]; +} diff --git a/lib/13/01___/route/parser.dart b/lib/13/01___/route/parser.dart new file mode 100644 index 0000000..0b5ece2 --- /dev/null +++ b/lib/13/01___/route/parser.dart @@ -0,0 +1,122 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:iroute/common/pages/stl_color_page.dart'; +import 'package:path_to_regexp/path_to_regexp.dart'; +import '../pages/app.dart'; +import '../pages/home_page.dart'; +import '../pages/color_add_page.dart'; +import 'parsed_route.dart'; +import 'route_state.dart'; + +class AppRouteParser extends RouteInformationParser { + @override + Future parseRouteInformation( + RouteInformation routeInformation) async { + print("=======parseRouteInformation:${routeInformation.uri.path}==================="); + + final uri = routeInformation.uri; + final path = uri.toString(); + final queryParams = uri.queryParameters; + + return ParsedRoute(path, queryParams); + } + + @override + RouteInformation? restoreRouteInformation(ParsedRoute configuration) { + print("=======restoreRouteInformation:${configuration}==================="); + return RouteInformation(uri: Uri.parse(configuration.path)); + } +} + +class AppRouterDelegate extends RouterDelegate + with ChangeNotifier, PopNavigatorRouterDelegateMixin { + + AppRouterDelegate({String initial = '/'}) { + _routes.add(ParsedRoute(initial, {})); + } + + final List _routes = []; + + @override + final GlobalKey navigatorKey = GlobalKey(); + + @override + ParsedRoute get currentConfiguration { + return _routes.last; + } + + Future go(String route) async { + ParsedRoute _route = await parser.parseRouteInformation(RouteInformation(uri: Uri.parse(route))); + if(_route!=_routes.last){ + _routes.add(_route); + } + notifyListeners(); + } + + final _addColorKey = const ValueKey('addColor'); + final _colorDetailKey = const ValueKey('ColorDetail'); + + @override + Widget build(BuildContext context) { + List pages = []; + + for (ParsedRoute route in _routes) { + Page? page = _buildPageByPath(route); + if(page!=null){ + pages.add(page); + } + } + + return Navigator( + key: navigatorKey, + pages: pages, + onPopPage: _onPagePop, + ); + } + + Page? _buildPageByPath(ParsedRoute route) { + if(route.path == '/'){ + return MaterialPage(child: HomePage()); + } + + if(route.path.startsWith('/color/detail')){ + String? selectedColor = route.queryParameters['color']; + + if (selectedColor != null) { + Color color = Color(int.parse(selectedColor, radix: 16)); + return MaterialPage(key: _colorDetailKey, child: StlColorPage(color: color)); + } + } + + if (route.path == '/color/add') { + return MaterialPage(key: _addColorKey, child: ColorAddPage()); + } + + return null; + } + + @override + Future setNewRoutePath(ParsedRoute configuration) async { + print("===setNewRoutePath===${configuration}================="); + if(configuration!=_routes.last){ + _routes.add(configuration); + } + } + + bool _onPagePop(Route route, result) { + RouteSettings settings = route.settings; + if(settings is Page){ + if(settings.key==_addColorKey){ + _routes.removeLast(); + notifyListeners(); + } + if(settings.key==_colorDetailKey){ + _routes.removeLast(); + notifyListeners(); + } + } + return route.didPop(result); + } + + +} diff --git a/lib/13/01___/route/route_state.dart b/lib/13/01___/route/route_state.dart new file mode 100644 index 0000000..8e8cfc2 --- /dev/null +++ b/lib/13/01___/route/route_state.dart @@ -0,0 +1,48 @@ +// 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/widgets.dart'; + +import 'parsed_route.dart'; +import 'parser.dart'; + +/// The current route state. To change the current route, call obtain the state +/// using `RouteStateScope.of(context)` and call `go()`: +/// +/// ``` +/// RouteStateScope.of(context).go('/book/2'); +/// ``` +class RouteState extends ChangeNotifier { + final AppRouteParser _parser; + ParsedRoute _route; + + RouteState(this._parser,{String initial=''}) : _route = ParsedRoute(initial,{}); + + ParsedRoute get route => _route; + + set route(ParsedRoute route) { + // Don't notify listeners if the path hasn't changed. + if (_route == route) return; + + _route = route; + notifyListeners(); + } + + Future go(String route) async { + this.route = await _parser + .parseRouteInformation(RouteInformation(uri: Uri.parse(route))); + } +} + +// /// Provides the current [RouteState] to descendant widgets in the tree. +// class RouteStateScope extends InheritedNotifier { +// const RouteStateScope({ +// required super.notifier, +// required super.child, +// super.key, +// }); +// +// static RouteState of(BuildContext context) => +// context.dependOnInheritedWidgetOfExactType()!.notifier!; +// } diff --git a/lib/13/01____/main.dart b/lib/13/01____/main.dart new file mode 100644 index 0000000..dc14a42 --- /dev/null +++ b/lib/13/01____/main.dart @@ -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()); +} + + + + diff --git a/lib/13/01____/pages/app/app.dart b/lib/13/01____/pages/app/app.dart new file mode 100644 index 0000000..e4d05e8 --- /dev/null +++ b/lib/13/01____/pages/app/app.dart @@ -0,0 +1,29 @@ +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: AppToolBar(), + body: Router(routerDelegate: router), + )); + } +} + diff --git a/lib/13/01____/pages/app/app_router_delegate.dart b/lib/13/01____/pages/app/app_router_delegate.dart new file mode 100644 index 0000000..5fded97 --- /dev/null +++ b/lib/13/01____/pages/app/app_router_delegate.dart @@ -0,0 +1,73 @@ +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 with ChangeNotifier, PopNavigatorRouterDelegateMixin { + + AppRouterDelegate({String initial = '/'}):_path=initial; + + String _path; + + String get path=> _path; + + void go(String path){ + _path = path; + notifyListeners(); + } + + @override + Widget build(BuildContext context) { + return Navigator( + onPopPage: _onPopPage, + pages: parserConfig(_path).map((e) => _pageMap[e]!).toList(), + ); + } + + final Map _pageMap = const { + '/': MaterialPage(child: HomePage()), + 'a': MaterialPage(child: PageA()), + 'b': MaterialPage(child: PageB()), + 'c': MaterialPage(child: PageC()), + }; + + Widget buildNavigatorByConfig(String path) { + return Navigator( + onPopPage: _onPopPage, + pages: parserConfig(path).map((e) => _pageMap[e]!).toList(), + ); + } + + bool _onPopPage(Route route, result) { + if(path.length>1){ + int last = path.lastIndexOf('/'); + _path = path.substring(0,last); + if(_path.isEmpty) _path = '/'; + notifyListeners(); + } + return route.didPop(result); + } + + @override + GlobalKey? navigatorKey = GlobalKey(); + + + @override + Future setNewRoutePath(String configuration) async{ + _path = configuration; + } + + List parserConfig(String path){ + /// 例: /a/b/c 进栈 /,a,b,c 界面 + List result = ['/']; + if(path.startsWith('/')){ + path = path.substring(1); + if(path.isNotEmpty){ + List parts = path.split('/'); + result.addAll(parts); + } + } + return result; + } +} \ No newline at end of file diff --git a/lib/13/01____/pages/app/app_tool_bar.dart b/lib/13/01____/pages/app/app_tool_bar.dart new file mode 100644 index 0000000..f9e1208 --- /dev/null +++ b/lib/13/01____/pages/app/app_tool_bar.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import '../../main.dart'; + +class AppToolBar extends StatefulWidget implements PreferredSizeWidget{ + const AppToolBar({super.key}); + + @override + State createState() => _AppToolBarState(); + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} + +class _AppToolBarState extends State { + + 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.path; + } + + @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.go(value); + } +} diff --git a/lib/13/01____/pages/home_page.dart b/lib/13/01____/pages/home_page.dart new file mode 100644 index 0000000..4b2f3a2 --- /dev/null +++ b/lib/13/01____/pages/home_page.dart @@ -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.go('/a'); + } +} diff --git a/lib/13/01____/pages/page_a.dart b/lib/13/01____/pages/page_a.dart new file mode 100644 index 0000000..97d2769 --- /dev/null +++ b/lib/13/01____/pages/page_a.dart @@ -0,0 +1,30 @@ +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']; + router.go('/a/b'); + } + +} diff --git a/lib/13/01____/pages/page_b.dart b/lib/13/01____/pages/page_b.dart new file mode 100644 index 0000000..ffdc5f0 --- /dev/null +++ b/lib/13/01____/pages/page_b.dart @@ -0,0 +1,32 @@ +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.go('/a/b/c'); + } + +} \ No newline at end of file diff --git a/lib/13/01____/pages/page_c.dart b/lib/13/01____/pages/page_c.dart new file mode 100644 index 0000000..ce3a8af --- /dev/null +++ b/lib/13/01____/pages/page_c.dart @@ -0,0 +1,24 @@ +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('到达终点'), + )); + } + + +} diff --git a/lib/13/02__/main.dart b/lib/13/02__/main.dart new file mode 100644 index 0000000..75b32c0 --- /dev/null +++ b/lib/13/02__/main.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:url_strategy/url_strategy.dart'; + +import 'pages/app.dart'; + + + +void main() { + setHashUrlStrategy(); + runApp(const App()); +} + + + + diff --git a/lib/13/02/pages/app.dart b/lib/13/02__/pages/app.dart similarity index 96% rename from lib/13/02/pages/app.dart rename to lib/13/02__/pages/app.dart index 650d6b4..bb1d39b 100644 --- a/lib/13/02/pages/app.dart +++ b/lib/13/02__/pages/app.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:iroute/13/02/store/app_state.dart'; +import '../store/app_state.dart'; import '../route/parser.dart'; import '../route/route_state.dart'; diff --git a/lib/13/02__/pages/color_add_page.dart b/lib/13/02__/pages/color_add_page.dart new file mode 100644 index 0000000..bee43b4 --- /dev/null +++ b/lib/13/02__/pages/color_add_page.dart @@ -0,0 +1,67 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class ColorAddPage extends StatefulWidget { + const ColorAddPage({super.key}); + + @override + State createState() => _ColorAddPageState(); +} + +class _ColorAddPageState extends State { + 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); + } +} diff --git a/lib/13/02/pages/home_page.dart b/lib/13/02__/pages/home_page.dart similarity index 95% rename from lib/13/02/pages/home_page.dart rename to lib/13/02__/pages/home_page.dart index a4653e6..7dd4549 100644 --- a/lib/13/02/pages/home_page.dart +++ b/lib/13/02__/pages/home_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:iroute/13/02/store/app_state.dart'; +import '../store/app_state.dart'; import '../route/route_state.dart'; import 'color_add_page.dart'; diff --git a/lib/13/02/route/parsed_route.dart b/lib/13/02__/route/parsed_route.dart similarity index 100% rename from lib/13/02/route/parsed_route.dart rename to lib/13/02__/route/parsed_route.dart diff --git a/lib/13/02/route/parser.dart b/lib/13/02__/route/parser.dart similarity index 100% rename from lib/13/02/route/parser.dart rename to lib/13/02__/route/parser.dart diff --git a/lib/13/02/route/route_state.dart b/lib/13/02__/route/route_state.dart similarity index 100% rename from lib/13/02/route/route_state.dart rename to lib/13/02__/route/route_state.dart diff --git a/lib/13/02/store/app_state.dart b/lib/13/02__/store/app_state.dart similarity index 100% rename from lib/13/02/store/app_state.dart rename to lib/13/02__/store/app_state.dart diff --git a/lib/13/go_color/main.dart b/lib/13/go_color/main.dart new file mode 100644 index 0000000..b396b4e --- /dev/null +++ b/lib/13/go_color/main.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:url_strategy/url_strategy.dart'; + +import 'pages/app.dart'; + +void main() { + setHashUrlStrategy(); + runApp(const App()); +} + + + + diff --git a/lib/13/go_color/pages/app.dart b/lib/13/go_color/pages/app.dart new file mode 100644 index 0000000..3b8ecca --- /dev/null +++ b/lib/13/go_color/pages/app.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:iroute/common/pages/stl_color_page.dart'; +import '../route/parser.dart'; +import 'home_page.dart'; +import 'color_add_page.dart'; + +class App extends StatefulWidget { + const App({super.key}); + + @override + State createState() => _AppState(); +} + +class _AppState extends State { + + GoRouter router = GoRouter( + initialLocation: '/color', + routes: [ + GoRoute(path: '/color',builder: (ctx,state)=>HomePage()), + GoRoute(path: '/color/detail',builder: (ctx,state) { + String selectedColor = state.uri.queryParameters['color']??''; + return StlColorPage( + color: Color(int.parse(selectedColor,radix: 16)), + ); + }), + GoRoute(path: '/color/add',builder: (ctx,state)=>ColorAddPage()), + ] + + ); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + routerConfig: router, + // backButtonDispatcher: RootBackButtonDispatcher(), + theme: ThemeData( + useMaterial3: true, + appBarTheme: const AppBarTheme( + elevation: 0, + iconTheme: IconThemeData(color: Colors.black), + titleTextStyle: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ))), + debugShowCheckedModeBanner: false, + ); + } +} diff --git a/lib/13/go_color/pages/color_add_page.dart b/lib/13/go_color/pages/color_add_page.dart new file mode 100644 index 0000000..bee43b4 --- /dev/null +++ b/lib/13/go_color/pages/color_add_page.dart @@ -0,0 +1,67 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class ColorAddPage extends StatefulWidget { + const ColorAddPage({super.key}); + + @override + State createState() => _ColorAddPageState(); +} + +class _ColorAddPageState extends State { + 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); + } +} diff --git a/lib/13/go_color/pages/home_page.dart b/lib/13/go_color/pages/home_page.dart new file mode 100644 index 0000000..6ed198f --- /dev/null +++ b/lib/13/go_color/pages/home_page.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import '../route/route_state.dart'; +import 'app.dart'; +import 'color_add_page.dart'; + +import '../../../common/components/colors_panel.dart'; +import '../../../common/pages/stl_color_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final List _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 + void dispose() { + print('_HomePageState#dispose'); + super.dispose(); + } + + @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); + context.push('/color/detail?color=$value'); + context.go('/color/detail?color=$value'); + // routerDelegate.go('/color/detail?color=$value'); + } + + void _toAddPage() async { + Color? color = await context.push('/color/add'); + if (color != null) { + setState(() { + _colors.add(color); + }); + } + } +} diff --git a/lib/13/go_color/route/parsed_route.dart b/lib/13/go_color/route/parsed_route.dart new file mode 100644 index 0000000..ea47fee --- /dev/null +++ b/lib/13/go_color/route/parsed_route.dart @@ -0,0 +1,21 @@ +// // 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:collection/collection.dart'; +// import 'package:equatable/equatable.dart'; +// import 'package:quiver/core.dart'; +// +// /// A route path that has been parsed by [TemplateRouteParser]. +// class ParsedRoute extends Equatable{ +// /// The current path location without query parameters. (/book/123) +// final String path; +// +// /// The query parameters ({search: abc}) +// final Map queryParameters; +// +// const ParsedRoute(this.path, this.queryParameters); +// +// @override +// List get props => [path,queryParameters]; +// } diff --git a/lib/13/go_color/route/parser.dart b/lib/13/go_color/route/parser.dart new file mode 100644 index 0000000..e6d2bdf --- /dev/null +++ b/lib/13/go_color/route/parser.dart @@ -0,0 +1,112 @@ +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; +// import 'package:iroute/common/pages/stl_color_page.dart'; +// import 'package:path_to_regexp/path_to_regexp.dart'; +// import '../pages/app.dart'; +// import '../pages/home_page.dart'; +// import '../pages/color_add_page.dart'; +// import 'parsed_route.dart'; +// import 'route_state.dart'; +// +// class AppRouteParser extends RouteInformationParser { +// +// @override +// Future parseRouteInformation( +// RouteInformation routeInformation) async { +// print("=======parseRouteInformation:${routeInformation.uri.path}==================="); +// +// final uri = routeInformation.uri; +// final path = uri.toString(); +// final queryParams = uri.queryParameters; +// +// return ParsedRoute(path, queryParams); +// } +// +// @override +// RouteInformation? restoreRouteInformation(ParsedRoute configuration) { +// print("=======restoreRouteInformation:${configuration}==================="); +// +// return RouteInformation(uri: Uri.parse(configuration.path)); +// } +// } +// +// ValueNotifier> router = ValueNotifier(['/']); +// +// class AppRouterDelegate extends RouterDelegate +// with ChangeNotifier, PopNavigatorRouterDelegateMixin { +// +// +// AppRouterDelegate({String initial='/'}) : _route = ParsedRoute(initial,{}); +// +// late ParsedRoute _route; +// +// @override +// final GlobalKey navigatorKey = GlobalKey(); +// +// @override +// ParsedRoute get currentConfiguration { +// return _route; +// } +// +// Future go(String route) async { +// _route = await parser.parseRouteInformation(RouteInformation(uri: Uri.parse(route))); +// notifyListeners(); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// final _addColorKey = const ValueKey('addColor'); +// +// @override +// Widget build(BuildContext context) { +// +// List pages =[]; +// final String path = _route.path; +// +// pages.add(MaterialPage(child: HomePage())); +// +// String? selectedColor; +// if (path.startsWith('/color/detail') ) { +// selectedColor = _route.queryParameters['color']; +// } +// +// if(selectedColor!=null){ +// pages.add(MaterialPage(child: StlColorPage( +// color: Color(int.parse(selectedColor,radix: 16)), +// ))); +// } +// +// bool isAddPage = path == '/color/add'; +// if(isAddPage){ +// pages.add(MaterialPage( +// key: _addColorKey, +// child: ColorAddPage()),); +// } +// +// return Navigator( +// key: navigatorKey, +// pages: pages, +// onPopPage: (route, result) { +// if (route.settings is Page && (route.settings as Page).key == _addColorKey) { +// go('/'); +// } +// +// if(selectedColor!=null){ +// selectedColor = null; +// go('/'); +// } +// return route.didPop(result); +// }, +// ); +// } +// +// @override +// Future setNewRoutePath(ParsedRoute configuration) async { +// print("===setNewRoutePath===${configuration}================="); +// _route = configuration; +// } +// +// } diff --git a/lib/13/go_color/route/route_state.dart b/lib/13/go_color/route/route_state.dart new file mode 100644 index 0000000..584bec8 --- /dev/null +++ b/lib/13/go_color/route/route_state.dart @@ -0,0 +1,48 @@ +// // 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/widgets.dart'; +// +// import 'parsed_route.dart'; +// import 'parser.dart'; +// +// /// The current route state. To change the current route, call obtain the state +// /// using `RouteStateScope.of(context)` and call `go()`: +// /// +// /// ``` +// /// RouteStateScope.of(context).go('/book/2'); +// /// ``` +// class RouteState extends ChangeNotifier { +// final AppRouteParser _parser; +// ParsedRoute _route; +// +// RouteState(this._parser,{String initial=''}) : _route = ParsedRoute(initial,{}); +// +// ParsedRoute get route => _route; +// +// set route(ParsedRoute route) { +// // Don't notify listeners if the path hasn't changed. +// if (_route == route) return; +// +// _route = route; +// notifyListeners(); +// } +// +// Future go(String route) async { +// this.route = await _parser +// .parseRouteInformation(RouteInformation(uri: Uri.parse(route))); +// } +// } +// +// // /// Provides the current [RouteState] to descendant widgets in the tree. +// // class RouteStateScope extends InheritedNotifier { +// // const RouteStateScope({ +// // required super.notifier, +// // required super.child, +// // super.key, +// // }); +// // +// // static RouteState of(BuildContext context) => +// // context.dependOnInheritedWidgetOfExactType()!.notifier!; +// // }