diff --git a/lib/03/01/main.dart b/lib/03/01/main.dart deleted file mode 100644 index d61d309..0000000 --- a/lib/03/01/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'pages/home_page.dart'; - - - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const HomePage(), - ); - } -} - - diff --git a/lib/03/01/pages/color_add_page.dart b/lib/03/01/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/03/01/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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/03/01/pages/home_page.dart b/lib/03/01/pages/home_page.dart deleted file mode 100644 index f8e303e..0000000 --- a/lib/03/01/pages/home_page.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.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){ - Route route = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color)); - Navigator.of(context).push(route); - } - - void _toAddPage() async { - Route route = MaterialPageRoute(builder: (ctx) => const ColorAddPage()); - Color? color = await Navigator.of(context).push(route); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/03/02/main.dart b/lib/03/02/main.dart deleted file mode 100644 index 3409614..0000000 --- a/lib/03/02/main.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:flutter/material.dart'; -import 'pages/color_add_page.dart'; -import '../../common/pages/stl_color_page.dart'; -import 'pages/empty_page.dart'; -import 'pages/home_page.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - routes: routeMap, - // initialRoute: '/add_color', - onUnknownRoute: _onUnknownRoute, - onGenerateRoute: _onGenerateRoute, - ); - } - - /// 路由映射 [字符串 --> 组件构造器] - Map get routeMap => { - '/': (ctx) => const HomePage(), - '/add_color': (ctx) => const ColorAddPage(), - }; - - /// 根据路由配置 [settings] 创建路由 - Route? _onGenerateRoute(RouteSettings settings) { - String? name = settings.name; - Widget? child; - if (name == '/color_detail') { - Color color = settings.arguments as Color; - child = StlColorPage(color: color); - } - - if (child != null) { - return MaterialPageRoute( - builder: (ctx) => child!, - settings: settings, - ); - } - return null; - } - - Route? _onUnknownRoute(RouteSettings settings) { - return MaterialPageRoute( - builder: (ctx) => const EmptyPage(), - settings: settings, - ); - } -} diff --git a/lib/03/02/pages/color_add_page.dart b/lib/03/02/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/03/02/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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/03/02/pages/home_page.dart b/lib/03/02/pages/home_page.dart deleted file mode 100644 index 76c90db..0000000 --- a/lib/03/02/pages/home_page.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.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('颜色主页 V2')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ); - } - - void _selectColor(Color color){ - Navigator.of(context).pushNamed('/color_detail1',arguments: color); - } - - void _toAddPage() async { - dynamic color = await Navigator.of(context).pushNamed('/add_color'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/03/03/main.dart b/lib/03/03/main.dart deleted file mode 100644 index 0e7ad2d..0000000 --- a/lib/03/03/main.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'router1/router1.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - - routes: Router1.routeMap, - navigatorKey: Router1.globalNavKey, - onUnknownRoute: Router1.onUnknownRoute, - initialRoute: Router1.initialRoute, - onGenerateRoute: Router1.onGenerateRoute, - ); - } -} diff --git a/lib/03/03/pages/color_add_page.dart b/lib/03/03/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/03/03/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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/03/03/pages/home_page.dart b/lib/03/03/pages/home_page.dart deleted file mode 100644 index 45773e0..0000000 --- a/lib/03/03/pages/home_page.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router1/router1.dart'; - -import '../../../common/components/colors_panel.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('颜色主页 V3')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ); - } - - void _selectColor(Color color){ - - Router1.nav.pushNamed(Router1.kColorDetail,arguments: color); - } - - void _toAddPage() async { - dynamic color = await Router1.nav.pushNamed(Router1.kAddColor); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/03/03/router1/router1.dart b/lib/03/03/router1/router1.dart deleted file mode 100644 index 9838f23..0000000 --- a/lib/03/03/router1/router1.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../common/pages/stl_color_page.dart'; -import '../pages/color_add_page.dart'; -import '../pages/empty_page.dart'; -import '../pages/home_page.dart'; - -class Router1 { - - /// 主页面 [HomePage] - static const String kHome = '/'; - - /// 颜色详情页 [StlColorPage] - static const String kColorDetail = '${kHome}color_detail'; - - /// 添加颜色页 [ColorAddPage] - static const String kAddColor = '${kHome}add_color'; - - - static String get initialRoute => kHome; - - static final GlobalKey globalNavKey = GlobalKey(); - - static NavigatorState get nav => globalNavKey.currentState!; - - /// 路由映射 [字符串 --> 组件构造器] - static Map get routeMap => { - kHome: (ctx) => const HomePage(), - kAddColor: (ctx) => const ColorAddPage(), - }; - - /// 根据路由配置 [settings] 创建路由 - static Route? onGenerateRoute(RouteSettings settings) { - String? name = settings.name; - Widget? child; - if (name == kColorDetail) { - Color color = settings.arguments as Color; - child = StlColorPage(color: color); - } - - if (child != null) { - return MaterialPageRoute( - builder: (ctx) => child!, - settings: settings, - ); - } - return null; - } - - static Route? onUnknownRoute(RouteSettings settings) { - return MaterialPageRoute( - builder: (ctx) => const EmptyPage(), - settings: settings, - ); - } -} diff --git a/lib/05/01/main.dart b/lib/05/01/main.dart deleted file mode 100644 index a80f1f6..0000000 --- a/lib/05/01/main.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(const OverlayPage()); -} - -class OverlayPage extends StatelessWidget{ - const OverlayPage({super.key}); - - @override - Widget build(BuildContext context) { - final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage()); - - return Directionality( - textDirection: TextDirection.ltr, - child: Overlay( - initialEntries: [home], - ), - ); - } -} - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - return const ColoredBox( - color: Colors.white, - child: Align( - child: FlutterLogo(size: 60,), - ), - ); - } -} - diff --git a/lib/05/02/main.dart b/lib/05/02/main.dart deleted file mode 100644 index 3d34b2a..0000000 --- a/lib/05/02/main.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(const OverlayPage()); -} - -class OverlayPage extends StatelessWidget{ - const OverlayPage({super.key}); - - @override - Widget build(BuildContext context) { - final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage()); - final OverlayEntry circle = OverlayEntry(builder: (BuildContext context) => const Center(child: Circle())); - - return Directionality( - textDirection: TextDirection.ltr, - child: Overlay( - initialEntries: [home,circle], - ), - ); - } -} - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - return const ColoredBox( - color: Colors.white, - child: Align( - child: FlutterLogo( - size: 60, - ), - ), - ); - } -} - -class Circle extends StatelessWidget { - const Circle({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - width: 20, - height: 20, - decoration: const BoxDecoration( - color: Colors.redAccent, - shape: BoxShape.circle - ), - ); - } -} diff --git a/lib/05/03/main.dart b/lib/05/03/main.dart deleted file mode 100644 index f6eae69..0000000 --- a/lib/05/03/main.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(const OverlayPage()); -} - -class OverlayPage extends StatelessWidget{ - const OverlayPage({super.key}); - - @override - Widget build(BuildContext context) { - final OverlayEntry home = - OverlayEntry(builder: (BuildContext context) => const HomePage()); - - final OverlayEntry circle = OverlayEntry( - builder: (BuildContext context) => Positioned( - top: 50, - left: 50, - child: const Circle(), - )); - - return Directionality( - textDirection: TextDirection.ltr, - child: Overlay( - initialEntries: [home, circle], - ), - ); - } -} - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - return const ColoredBox( - color: Colors.white, - child: Align( - child: FlutterLogo( - size: 60, - ), - ), - ); - } -} - -class Circle extends StatelessWidget { - const Circle({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - width: 20, - height: 20, - decoration: - const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle), - ); - } -} diff --git a/lib/05/04/main.dart b/lib/05/04/main.dart deleted file mode 100644 index 0648355..0000000 --- a/lib/05/04/main.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(const OverlayPage()); -} - -class OverlayPage extends StatefulWidget { - const OverlayPage({super.key}); - - @override - State createState() => _OverlayPageState(); -} - -class _OverlayPageState extends State { - double _left = 0; - double _top = 0; - - @override - Widget build(BuildContext context) { - final OverlayEntry home = - OverlayEntry(builder: (BuildContext context) => const HomePage()); - - final OverlayEntry circle = OverlayEntry( - builder: (BuildContext context) => Positioned( - top: 50, - left: 50, - child: GestureDetector( - onPanUpdate: _updatePosition, - child: const Circle(), - ), - )); - - return Directionality( - textDirection: TextDirection.ltr, - child: Overlay( - initialEntries: [home, circle], - ), - ); - } - - void _updatePosition(DragUpdateDetails details) { - setState(() { - _top += details.delta.dy; - _left += details.delta.dx; - }); - } -} - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - return const ColoredBox( - color: Colors.white, - child: Align( - child: FlutterLogo( - size: 60, - ), - ), - ); - } -} - -class Circle extends StatelessWidget { - const Circle({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - width: 20, - height: 20, - decoration: - const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle), - ); - } -} diff --git a/lib/05/05/main.dart b/lib/05/05/main.dart deleted file mode 100644 index 8e14ff8..0000000 --- a/lib/05/05/main.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(const OverlayPage()); -} - -class OverlayPage extends StatefulWidget { - const OverlayPage({super.key}); - - @override - State createState() => _OverlayPageState(); -} - -class _OverlayPageState extends State { - @override - Widget build(BuildContext context) { - final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage()); - return Directionality( - textDirection: TextDirection.ltr, - child: Overlay( - initialEntries: [home], - ), - ); - } -} - -class HomePage extends StatefulWidget { - const HomePage({super.key}); - - @override - State createState() => _HomePageState(); -} - -class _HomePageState extends State { - - OverlayEntry? entry; - - @override - Widget build(BuildContext context) { - return ColoredBox( - color: Colors.white, - child: Align( - child: GestureDetector( - onTap: _toggle, - child: const FlutterLogo( - size: 60, - ), - ), - ), - ); - } - - void _toggle() { - if(entry==null){ - entry = _createPoint(); - Overlay.of(context).insert(entry!); - }else{ - entry!.remove(); - entry = null; - } - } - - OverlayEntry _createPoint() { - return OverlayEntry( - builder: (BuildContext context) => Positioned( - width: 20, - height: 20, - left: 20, - top: 20, - child: GestureDetector(child: const Circle()), - ), - ); - } -} - -class ClickShowPage extends StatefulWidget { - const ClickShowPage({super.key}); - - @override - State createState() => _ClickShowPageState(); -} - -class _ClickShowPageState extends State { - Offset _position = Offset.zero; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: _addPoint, - onTapDown: _onTapDown, - ); - } - - void _addPoint() { - OverlayEntry entry = _createPoint(); - Overlay.of(context).insert(entry); - } - - OverlayEntry _createPoint() { - return OverlayEntry( - builder: (BuildContext context) => Positioned( - width: 20, - height: 20, - left: _position.dx - 10, - top: _position.dy - 10, - child: Circle()), - ); - } - - void _onTapDown(TapDownDetails details) { - _position = details.localPosition; - } -} - -class Circle extends StatelessWidget { - const Circle({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - width: 20, - height: 20, - decoration: - const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle), - ); - } -} diff --git a/lib/05/06/main.dart b/lib/05/06/main.dart deleted file mode 100644 index d61d309..0000000 --- a/lib/05/06/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'pages/home_page.dart'; - - - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const HomePage(), - ); - } -} - - diff --git a/lib/05/06/pages/color_add_page.dart b/lib/05/06/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/05/06/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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/05/06/pages/home_page.dart b/lib/05/06/pages/home_page.dart deleted file mode 100644 index f8e303e..0000000 --- a/lib/05/06/pages/home_page.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.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){ - Route route = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color)); - Navigator.of(context).push(route); - } - - void _toAddPage() async { - Route route = MaterialPageRoute(builder: (ctx) => const ColorAddPage()); - Color? color = await Navigator.of(context).push(route); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/06/01/main.dart b/lib/06/01/main.dart deleted file mode 100644 index d61d309..0000000 --- a/lib/06/01/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'pages/home_page.dart'; - - - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const HomePage(), - ); - } -} - - diff --git a/lib/06/01/pages/color_add_page.dart b/lib/06/01/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/06/01/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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/06/01/pages/home_page.dart b/lib/06/01/pages/home_page.dart deleted file mode 100644 index f8e303e..0000000 --- a/lib/06/01/pages/home_page.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.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){ - Route route = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color)); - Navigator.of(context).push(route); - } - - void _toAddPage() async { - Route route = MaterialPageRoute(builder: (ctx) => const ColorAddPage()); - Color? color = await Navigator.of(context).push(route); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/06/02/main.dart b/lib/06/02/main.dart deleted file mode 100644 index 5d5047c..0000000 --- a/lib/06/02/main.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; -import 'pages/page_b.dart'; -import 'pages/home_page.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - initialRoute: '/a/b', - onGenerateRoute: _onGenerateRoute, - ); - } - - Route? _onGenerateRoute(RouteSettings settings) { - String? name = settings.name; - Widget? page ; - if(name=='/'){ - page = const HomePage(); - } - if(name=='/a'){ - page = const PageA(); - } - if(name=='/a/b'){ - page = const PageB(); - } - - if(page!=null){ - return MaterialPageRoute(builder: (_)=> page!,settings: settings); - } - return null; - } -} diff --git a/lib/06/02/pages/home_page.dart b/lib/06/02/pages/home_page.dart deleted file mode 100644 index f1579ab..0000000 --- a/lib/06/02/pages/home_page.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - 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){ - Navigator.of(context).pushNamed('/a'); - } -} diff --git a/lib/06/02/pages/page_a.dart b/lib/06/02/pages/page_a.dart deleted file mode 100644 index 940ff84..0000000 --- a/lib/06/02/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB())); - } -} diff --git a/lib/06/02/pages/page_b.dart b/lib/06/02/pages/page_b.dart deleted file mode 100644 index f7a1814..0000000 --- a/lib/06/02/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'home_page.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('回到主界面'), - ), - ), - ); - } - - void toPageC(BuildContext context){ - Navigator.of(context).popUntil(ModalRoute.withName('/')); - } -} \ No newline at end of file diff --git a/lib/07/01/main.dart b/lib/07/01/main.dart deleted file mode 100644 index 27f540b..0000000 --- a/lib/07/01/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - home: const PageA(), - ); - } -} diff --git a/lib/07/01/pages/page_a.dart b/lib/07/01/pages/page_a.dart deleted file mode 100644 index 940ff84..0000000 --- a/lib/07/01/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB())); - } -} diff --git a/lib/07/01/pages/page_b.dart b/lib/07/01/pages/page_b.dart deleted file mode 100644 index a132264..0000000 --- a/lib/07/01/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_c.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){ - Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageC())); - } -} \ No newline at end of file diff --git a/lib/07/01/pages/page_c.dart b/lib/07/01/pages/page_c.dart deleted file mode 100644 index ac595f0..0000000 --- a/lib/07/01/pages/page_c.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class PageC extends StatelessWidget { - const PageC({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('C'), - backgroundColor: bgColor, - ), - body: const Center( - child: Text('到达终点'), - ), - ); - } -} diff --git a/lib/07/节点介绍.txt b/lib/07/节点介绍.txt deleted file mode 100644 index b50e9a9..0000000 --- a/lib/07/节点介绍.txt +++ /dev/null @@ -1,4 +0,0 @@ -01: 分析 push 方法。 - A、B、C 三个界面跳转。 - -02: replace \ No newline at end of file diff --git a/lib/08/01/main.dart b/lib/08/01/main.dart deleted file mode 100644 index 27f540b..0000000 --- a/lib/08/01/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - home: const PageA(), - ); - } -} diff --git a/lib/08/01/pages/page_a.dart b/lib/08/01/pages/page_a.dart deleted file mode 100644 index 49e5c38..0000000 --- a/lib/08/01/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> const PageB())); - } -} diff --git a/lib/08/01/pages/page_b.dart b/lib/08/01/pages/page_b.dart deleted file mode 100644 index 6149991..0000000 --- a/lib/08/01/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_c.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){ - Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> const PageC())); - } -} \ No newline at end of file diff --git a/lib/08/01/pages/page_c.dart b/lib/08/01/pages/page_c.dart deleted file mode 100644 index ac595f0..0000000 --- a/lib/08/01/pages/page_c.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class PageC extends StatelessWidget { - const PageC({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('C'), - backgroundColor: bgColor, - ), - body: const Center( - child: Text('到达终点'), - ), - ); - } -} diff --git a/lib/08/02/main.dart b/lib/08/02/main.dart deleted file mode 100644 index 346b963..0000000 --- a/lib/08/02/main.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; -import 'pages/page_b.dart'; -import 'pages/page_c.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - home: const PageA(), - onUnknownRoute: _onUnknownRoute, - ); - } - - Route? _onUnknownRoute(RouteSettings settings) { - String? name = settings.name; - Widget? page ; - if(name=='/a'){ - page = const PageA(); - } - if(name=='/b'){ - page = const PageB(); - } - if(name=='/c'){ - page = const PageC(); - } - if(page!=null){ - return MaterialPageRoute(builder: (_)=> page!,settings: settings); - } - return null; - } -} diff --git a/lib/08/02/pages/page_a.dart b/lib/08/02/pages/page_a.dart deleted file mode 100644 index 805b165..0000000 --- a/lib/08/02/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).pushNamed('/b'); - } -} diff --git a/lib/08/02/pages/page_b.dart b/lib/08/02/pages/page_b.dart deleted file mode 100644 index b36561e..0000000 --- a/lib/08/02/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_c.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){ - Navigator.of(context).pushNamed('/c'); - } -} \ No newline at end of file diff --git a/lib/08/02/pages/page_c.dart b/lib/08/02/pages/page_c.dart deleted file mode 100644 index 10b7a19..0000000 --- a/lib/08/02/pages/page_c.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_d.dart'; - -class PageC extends StatelessWidget { - const PageC({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('C'), - backgroundColor: bgColor, - ), - body: Center( - child: ElevatedButton( - onPressed: ()=>toPageD(context), - child: const Text('Push D Remove Until A'), - ), - ), - ); - } - - void toPageD(BuildContext context){ - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute(builder: (BuildContext context) => const PageD()), - ModalRoute.withName('/a'), - ); - } -} - - - diff --git a/lib/08/02/pages/page_d.dart b/lib/08/02/pages/page_d.dart deleted file mode 100644 index dda11df..0000000 --- a/lib/08/02/pages/page_d.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/06/02/pages/page_a.dart'; - -class PageD extends StatelessWidget { - const PageD({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFCCFF); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('D'), - backgroundColor: bgColor, - ), - body: Center( - child: const Text('到达终点'), - ), - ); - } -} diff --git a/lib/08/节点介绍.txt b/lib/08/节点介绍.txt deleted file mode 100644 index c7300da..0000000 --- a/lib/08/节点介绍.txt +++ /dev/null @@ -1,5 +0,0 @@ -01: 分析 pushReplacement 方法。 - A、B、C 三个界面跳转。 - -02: 分析 pushAndRemoveUntil 方法。 - A、B、C、D 四个界面跳转。 \ No newline at end of file diff --git a/lib/09/01/main.dart b/lib/09/01/main.dart deleted file mode 100644 index 27f540b..0000000 --- a/lib/09/01/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - home: const PageA(), - ); - } -} diff --git a/lib/09/01/pages/page_a.dart b/lib/09/01/pages/page_a.dart deleted file mode 100644 index 940ff84..0000000 --- a/lib/09/01/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB())); - } -} diff --git a/lib/09/01/pages/page_b.dart b/lib/09/01/pages/page_b.dart deleted file mode 100644 index a132264..0000000 --- a/lib/09/01/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_c.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){ - Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageC())); - } -} \ No newline at end of file diff --git a/lib/09/01/pages/page_c.dart b/lib/09/01/pages/page_c.dart deleted file mode 100644 index 5a1957a..0000000 --- a/lib/09/01/pages/page_c.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; - -class PageC extends StatelessWidget { - const PageC({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('C'), - backgroundColor: bgColor, - leading: BackButton( - onPressed: (){ - Navigator.of(context).pop(); - }, - ), - ), - body: const Center( - child: Text('到达终点'), - ), - ); - } -} diff --git a/lib/09/02/main.dart b/lib/09/02/main.dart deleted file mode 100644 index d966c58..0000000 --- a/lib/09/02/main.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/page_a.dart'; -import 'pages/page_b.dart'; -import 'pages/page_c.dart'; -import 'pages/home_page.dart'; -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - appBarTheme: AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold) - ) - ), - onUnknownRoute: _onUnknownRoute, - ); - } - - Route? _onUnknownRoute(RouteSettings settings) { - String? name = settings.name; - Widget? page ; - if(name=='/'){ - page = const HomePage(); - } - if(name=='/a'){ - page = const PageA(); - } - if(name=='/b'){ - page = const PageB(); - } - if(name=='/c'){ - page = const PageC(); - } - if(page!=null){ - return MaterialPageRoute(builder: (_)=> page!,settings: settings); - } - return null; - } -} diff --git a/lib/09/02/pages/home_page.dart b/lib/09/02/pages/home_page.dart deleted file mode 100644 index ebb98b5..0000000 --- a/lib/09/02/pages/home_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/06/02/pages/page_a.dart'; - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFCCFF); - - 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){ - Navigator.of(context).pushNamed('/a'); - } -} diff --git a/lib/09/02/pages/page_a.dart b/lib/09/02/pages/page_a.dart deleted file mode 100644 index 805b165..0000000 --- a/lib/09/02/pages/page_a.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'page_b.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){ - Navigator.of(context).pushNamed('/b'); - } -} diff --git a/lib/09/02/pages/page_b.dart b/lib/09/02/pages/page_b.dart deleted file mode 100644 index b36561e..0000000 --- a/lib/09/02/pages/page_b.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'page_c.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){ - Navigator.of(context).pushNamed('/c'); - } -} \ No newline at end of file diff --git a/lib/09/02/pages/page_c.dart b/lib/09/02/pages/page_c.dart deleted file mode 100644 index f6ffee8..0000000 --- a/lib/09/02/pages/page_c.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; - - -class PageC extends StatelessWidget { - const PageC({super.key}); - - @override - Widget build(BuildContext context) { - const Color bgColor = Color(0xffFFE6CD); - - return Scaffold( - backgroundColor: bgColor, - appBar: AppBar( - title: const Text('C'), - backgroundColor: bgColor, - ), - body: Center( - child: ElevatedButton( - onPressed: ()=>toPageD(context), - child: const Text('pop Until A'), - ), - ), - ); - } - - void toPageD(BuildContext context){ - Navigator.of(context).popUntil( - ModalRoute.withName('/a') - ); - } -} - - - diff --git a/lib/12/01/main.dart b/lib/12/01/main.dart deleted file mode 100644 index 0ecfe3f..0000000 --- a/lib/12/01/main.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; -import 'pages/app/app.dart'; - - -void main() { - runApp(const App()); -} - - - - diff --git a/lib/12/01/pages/app/app.dart b/lib/12/01/pages/app/app.dart deleted file mode 100644 index ba3946c..0000000 --- a/lib/12/01/pages/app/app.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_navigation.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: const Scaffold( - appBar: AppToolBar(), - body: AppNavigation(), - )); - } -} - diff --git a/lib/12/01/pages/app/app_navigation.dart b/lib/12/01/pages/app/app_navigation.dart deleted file mode 100644 index 75780da..0000000 --- a/lib/12/01/pages/app/app_navigation.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import '../page_a.dart'; -import '../page_b.dart'; -import '../page_c.dart'; -import '../home_page.dart'; - -ValueNotifier> router = ValueNotifier(['/']); - -class AppNavigation extends StatefulWidget { - const AppNavigation({super.key}); - - @override - State createState() => _AppNavigationState(); -} - -class _AppNavigationState extends State { - - - @override - void dispose() { - router.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ValueListenableBuilder( - valueListenable: router, - builder: (_, List value, __) => buildNavigatorByConfig(value), - ); - } - - final Map _pageMap = const { - '/': MaterialPage(child: HomePage()), - 'a': MaterialPage(child: PageA()), - 'b': MaterialPage(child: PageB()), - 'c': MaterialPage(child: PageC()), - }; - - Widget buildNavigatorByConfig(List value) { - return Navigator( - onPopPage: _onPopPage, - pages: router.value.map((e) => _pageMap[e]!).toList(), - ); - } - - bool _onPopPage(Route route, result) { - return route.didPop(result); - } -} diff --git a/lib/12/01/pages/app/app_tool_bar.dart b/lib/12/01/pages/app/app_tool_bar.dart deleted file mode 100644 index 002f6fd..0000000 --- a/lib/12/01/pages/app/app_tool_bar.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/material.dart'; -import 'app_navigation.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/12/01/pages/home_page.dart b/lib/12/01/pages/home_page.dart deleted file mode 100644 index 2f9001a..0000000 --- a/lib/12/01/pages/home_page.dart +++ /dev/null @@ -1,29 +0,0 @@ - -import 'package:flutter/material.dart'; - -import 'app/app_navigation.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']; - } -} diff --git a/lib/12/01/pages/page_a.dart b/lib/12/01/pages/page_a.dart deleted file mode 100644 index 0914954..0000000 --- a/lib/12/01/pages/page_a.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; -import 'app/app_navigation.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, - leading: BackButton(onPressed: _pop), - ), - body: Center( - child: ElevatedButton( - onPressed: () => toPageB(context), - child: const Text('Push B'), - ), - )); - } - - void toPageB(BuildContext context) { - router.value = ['/', 'a', 'b']; - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} diff --git a/lib/12/01/pages/page_b.dart b/lib/12/01/pages/page_b.dart deleted file mode 100644 index bf4eb83..0000000 --- a/lib/12/01/pages/page_b.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app/app_navigation.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, - leading: BackButton( - onPressed: _pop, - ), - ), - body: Center( - child: ElevatedButton( - onPressed: () => toPageC(context), - child: const Text('Push C'), - ), - )); - } - - - void toPageC(BuildContext context){ - router.value = ['/','a','b','c']; - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} \ No newline at end of file diff --git a/lib/12/01/pages/page_c.dart b/lib/12/01/pages/page_c.dart deleted file mode 100644 index 7cd165b..0000000 --- a/lib/12/01/pages/page_c.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app/app_navigation.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, - leading: BackButton(onPressed: _pop), - ), - body: Center( - child: Text('到达终点'), - )); - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} diff --git a/lib/13/01/main.dart b/lib/13/01/main.dart deleted file mode 100644 index dc14a42..0000000 --- a/lib/13/01/main.dart +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index 2652869..0000000 --- a/lib/13/01/pages/app/app.dart +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index 6902e2e..0000000 --- a/lib/13/01/pages/app/app_router_delegate.dart +++ /dev/null @@ -1,92 +0,0 @@ -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('=======popRoute========='); - return true; - } - - bool _onPopPage(Route route, result) { - 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 deleted file mode 100644 index dc6eff8..0000000 --- a/lib/13/01/pages/app/app_tool_bar.dart +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index 0c19d8d..0000000 --- a/lib/13/01/pages/home_page.dart +++ /dev/null @@ -1,30 +0,0 @@ - -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']; - } -} diff --git a/lib/13/01/pages/page_a.dart b/lib/13/01/pages/page_a.dart deleted file mode 100644 index 0ab03bf..0000000 --- a/lib/13/01/pages/page_a.dart +++ /dev/null @@ -1,33 +0,0 @@ -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, - leading: BackButton(onPressed: _pop), - ), - body: Center( - child: ElevatedButton( - onPressed: () => toPageB(context), - child: const Text('Push B'), - ), - )); - } - - void toPageB(BuildContext context) { - router.value = ['/', 'a', 'b']; - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} diff --git a/lib/13/01/pages/page_b.dart b/lib/13/01/pages/page_b.dart deleted file mode 100644 index 2cc386f..0000000 --- a/lib/13/01/pages/page_b.dart +++ /dev/null @@ -1,35 +0,0 @@ -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, - leading: BackButton(onPressed: _pop), - ), - body: Center( - child: ElevatedButton( - onPressed: () => toPageC(context), - child: const Text('Push C'), - ), - )); - } - - void toPageC(BuildContext context){ - router.value = ['/','a','b','c']; - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} \ No newline at end of file diff --git a/lib/13/01/pages/page_c.dart b/lib/13/01/pages/page_c.dart deleted file mode 100644 index 4d1e5ed..0000000 --- a/lib/13/01/pages/page_c.dart +++ /dev/null @@ -1,27 +0,0 @@ -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, - leading: BackButton(onPressed: _pop), - ), - body: Center( - child: Text('到达终点'), - )); - } - - void _pop() { - router.value = List.of(router.value)..removeLast(); - } -} diff --git a/lib/13/01_/main.dart b/lib/13/01_/main.dart deleted file mode 100644 index 75b32c0..0000000 --- a/lib/13/01_/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index cfd36b8..0000000 --- a/lib/13/01_/pages/app.dart +++ /dev/null @@ -1,50 +0,0 @@ -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(initialRoute: '/color', allowPaths: [ - '/color', - '/color/add', - '/color/detail/:colorHex', - ]); - _routeState = RouteState(_parser); - _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/01_/pages/color_add_page.dart b/lib/13/01_/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/13/01_/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 47b4dc9..0000000 --- a/lib/13/01_/pages/home_page.dart +++ /dev/null @@ -1,46 +0,0 @@ -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 deleted file mode 100644 index f03f0a8..0000000 --- a/lib/13/01_/route/parsed_route.dart +++ /dev/null @@ -1,27 +0,0 @@ -// 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 path template (/book/:id) - final String pathTemplate; - - /// The path parameters ({id: 123}) - final Map parameters; - - /// The query parameters ({search: abc}) - final Map queryParameters; - - const ParsedRoute(this.path, this.pathTemplate, this.parameters, this.queryParameters); - - @override - List get props => [path,pathTemplate,parameters,queryParameters]; -} diff --git a/lib/13/01_/route/parser.dart b/lib/13/01_/route/parser.dart deleted file mode 100644 index bb85717..0000000 --- a/lib/13/01_/route/parser.dart +++ /dev/null @@ -1,135 +0,0 @@ -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 { - final List allowPaths; - final ParsedRoute initialRoute; - - AppRouteParser({ - required this.allowPaths, - String initialRoute = '/', - }):initialRoute = ParsedRoute(initialRoute, initialRoute, {}, {}); - - @override - Future parseRouteInformation( - RouteInformation routeInformation) async { - print("=======parseRouteInformation:${routeInformation.uri.path}==================="); - - final uri = routeInformation.uri; - final path = uri.toString(); - final queryParams = uri.queryParameters; - - ParsedRoute parsedRoute = initialRoute; - - for (var pathTemplate in allowPaths) { - final parameters = []; - var pathRegExp = pathToRegExp(pathTemplate, parameters: parameters); - if (pathRegExp.hasMatch(path)) { - final match = pathRegExp.matchAsPrefix(path); - if (match == null) continue; - final params = extract(parameters, match); - parsedRoute = ParsedRoute(path, pathTemplate, params, queryParams); - } - } - return parsedRoute; - } - - @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 pathTemplate = routeState.route.pathTemplate; - - pages.add(MaterialPage(child: HomePage())); - - String? selectedColor; - if (pathTemplate == '/color/detail/:colorHex') { - selectedColor = routeState.route.parameters['colorHex']; - } - - if(selectedColor!=null){ - pages.add(MaterialPage(child: StlColorPage( - color: Colors.redAccent, - ))); - } - - bool isAddPage = pathTemplate == '/color/add'; - if(isAddPage){ - pages.add(MaterialPage( - key: _addColorKey, - child: ColorAddPage())); - } - print("===build===================="); - return Navigator( - key: navigatorKey, - pages: pages, - onPopPage: (route, result) { - print(result); - if (route.settings is Page && - (route.settings as Page).key == _addColorKey) { - routeState.go('/color'); - } - // appState.selectedBook = null; - // notifyListeners(); - 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 deleted file mode 100644 index a2d2e0f..0000000 --- a/lib/13/01_/route/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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) : _route = _parser.initialRoute; - - 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 deleted file mode 100644 index 75b32c0..0000000 --- a/lib/13/01__/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 11ff90f..0000000 --- a/lib/13/01__/pages/app.dart +++ /dev/null @@ -1,46 +0,0 @@ -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/01__/pages/color_add_page.dart b/lib/13/01__/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/13/01__/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index b5b949c..0000000 --- a/lib/13/01__/pages/home_page.dart +++ /dev/null @@ -1,46 +0,0 @@ -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 deleted file mode 100644 index f2bfb70..0000000 --- a/lib/13/01__/route/parsed_route.dart +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 0244de3..0000000 --- a/lib/13/01__/route/parser.dart +++ /dev/null @@ -1,119 +0,0 @@ -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 deleted file mode 100644 index d21a397..0000000 --- a/lib/13/01__/route/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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 deleted file mode 100644 index 75b32c0..0000000 --- a/lib/13/01___/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index c2013fe..0000000 --- a/lib/13/01___/pages/app.dart +++ /dev/null @@ -1,36 +0,0 @@ -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 deleted file mode 100644 index bee43b4..0000000 --- a/lib/13/01___/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 54decfb..0000000 --- a/lib/13/01___/pages/home_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index f2bfb70..0000000 --- a/lib/13/01___/route/parsed_route.dart +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 0b5ece2..0000000 --- a/lib/13/01___/route/parser.dart +++ /dev/null @@ -1,122 +0,0 @@ -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 deleted file mode 100644 index 8e8cfc2..0000000 --- a/lib/13/01___/route/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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 deleted file mode 100644 index dc14a42..0000000 --- a/lib/13/01____/main.dart +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index e4d05e8..0000000 --- a/lib/13/01____/pages/app/app.dart +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index 5fded97..0000000 --- a/lib/13/01____/pages/app/app_router_delegate.dart +++ /dev/null @@ -1,73 +0,0 @@ -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 deleted file mode 100644 index f9e1208..0000000 --- a/lib/13/01____/pages/app/app_tool_bar.dart +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index 4b2f3a2..0000000 --- a/lib/13/01____/pages/home_page.dart +++ /dev/null @@ -1,30 +0,0 @@ - -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 deleted file mode 100644 index 97d2769..0000000 --- a/lib/13/01____/pages/page_a.dart +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index ffdc5f0..0000000 --- a/lib/13/01____/pages/page_b.dart +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index ce3a8af..0000000 --- a/lib/13/01____/pages/page_c.dart +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index d273e50..0000000 --- a/lib/13/02/main.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:window_manager/window_manager.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/02/pages/app/app.dart b/lib/13/02/pages/app/app.dart deleted file mode 100644 index df39496..0000000 --- a/lib/13/02/pages/app/app.dart +++ /dev/null @@ -1,30 +0,0 @@ -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(), - ), - )); - } -} diff --git a/lib/13/02/pages/app/app_router_delegate.dart b/lib/13/02/pages/app/app_router_delegate.dart deleted file mode 100644 index b84f1dc..0000000 --- a/lib/13/02/pages/app/app_router_delegate.dart +++ /dev/null @@ -1,93 +0,0 @@ -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('=======popRoute========='); - return true; - } - - bool _onPopPage(Route route, result) { - value = List.of(_value)..removeLast(); - 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/02/pages/app/app_tool_bar.dart b/lib/13/02/pages/app/app_tool_bar.dart deleted file mode 100644 index dc6eff8..0000000 --- a/lib/13/02/pages/app/app_tool_bar.dart +++ /dev/null @@ -1,64 +0,0 @@ -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/02/pages/home_page.dart b/lib/13/02/pages/home_page.dart deleted file mode 100644 index 0c19d8d..0000000 --- a/lib/13/02/pages/home_page.dart +++ /dev/null @@ -1,30 +0,0 @@ - -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']; - } -} diff --git a/lib/13/02/pages/page_a.dart b/lib/13/02/pages/page_a.dart deleted file mode 100644 index 6e454bc..0000000 --- a/lib/13/02/pages/page_a.dart +++ /dev/null @@ -1,29 +0,0 @@ -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/02/pages/page_b.dart b/lib/13/02/pages/page_b.dart deleted file mode 100644 index 84d47f3..0000000 --- a/lib/13/02/pages/page_b.dart +++ /dev/null @@ -1,30 +0,0 @@ -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/02/pages/page_c.dart b/lib/13/02/pages/page_c.dart deleted file mode 100644 index f7d0823..0000000 --- a/lib/13/02/pages/page_c.dart +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 881b6ec..0000000 --- a/lib/13/02_/main.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/app/app.dart'; - - - -void main() { - runApp(const App()); -} - - - - diff --git a/lib/13/02_/menus.dart b/lib/13/02_/menus.dart deleted file mode 100644 index 8533c5d..0000000 --- a/lib/13/02_/menus.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:toly_menu/toly_menu.dart'; - -List menus = [ - MenuData(path: '/dashboard', label: '总览面板', children: [ - MenuData(path: '/dashboard/data_analyse', label: '数据分析', deep: 1), - MenuData(path: '/dashboard/work_board', label: '工作台', deep: 1, children: [ - MenuData(path: '/dashboard/work_board/a', label: '第一工作区', deep: 2), - MenuData(path: '/dashboard/work_board/b', label: '第二工作区', deep: 2), - MenuData(path: '/dashboard/work_board/c', label: '第三工作区', deep: 2), - ]), - ]), - MenuData(path: '/cases', label: '案例演示', children: [ - MenuData(path: '/cases/counter', label: '计数器项目', deep: 1), - MenuData(path: '/cases/guess', label: '猜数字项目', deep: 1), - MenuData(path: '/cases/muyu', label: '电子木鱼项目', deep: 1), - MenuData(path: '/cases/canvas', label: '白板绘制项目', deep: 1), - MenuData(path: '/cases/timer', label: '计时器项目', deep: 1), - ]), - MenuData(path: '/manager', label: '系统管理', children: [ - MenuData(path: '/manager/account', label: '账号管理', deep: 1), - MenuData(path: '/manager/role', label: '角色管理', deep: 1), - MenuData(path: '/manager/menu', label: '菜单管理', deep: 1), - ]), - MenuData(path: '/knowledge', label: '知识库管理', children: [ - MenuData(path: '/knowledge/a', label: '语文知识', deep: 1, children: [ - MenuData( - path: '/knowledge/a/1', - label: '诗词歌赋', - deep: 2, - ), - MenuData( - path: '/knowledge/a/2', - label: '人物故事', - deep: 2, - ), - MenuData( - path: '/knowledge/a/3', - label: '名著推荐', - deep: 2, - ) - ]), - MenuData( - path: '/knowledge/b', - label: '数学知识', - children: [ - MenuData( - path: '/knowledge/b/1', - label: '人物故事', - deep: 2, - ), - MenuData( - path: '/knowledge/b/2', - label: '数学定理', - deep: 2, - ), - MenuData( - path: '/knowledge/b/3', - label: '几何知识', - deep: 2, - ), - MenuData( - path: '/knowledge/b/4', - label: '代数知识', - deep: 2, - ) - ], - deep: 1), - MenuData( - path: '/knowledge/c', - label: '英语知识', - deep: 1, - ), - ]), - MenuData(path: '/widgets', label: '组件集录', children: [ - MenuData(path: '/widgets/stateless', label: '无状态组件', deep: 1), - MenuData(path: '/widgets/stateful', label: '有状态组件', deep: 1), - MenuData(path: '/widgets/single_child', label: '单子渲染组件', deep: 1), - MenuData(path: '/widgets/mutli_child', label: '多子渲染组件', deep: 1), - MenuData(path: '/widgets/sliver', label: '滑片组件', deep: 1), - MenuData(path: '/widgets/proxy', label: '代理组件', deep: 1), - MenuData(path: '/widgets/other', label: '其他组件', deep: 1), - ]) -]; diff --git a/lib/13/02_/pages/app/app.dart b/lib/13/02_/pages/app/app.dart deleted file mode 100644 index 3349008..0000000 --- a/lib/13/02_/pages/app/app.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:toly_menu/toly_menu.dart'; - -import '../../menus.dart'; -import '../../transition/fade_transition.dart'; -import 'root_content.dart'; - -class App extends StatelessWidget { - const App({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - theme: ThemeData( - pageTransitionsTheme: PageTransitionsTheme( - builders: { - TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadeUpwardsPageTransitionsBuilder(), - TargetPlatform.windows: FadeTransitionsBuilder(), - } - ), - - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - backgroundColor: Colors.white, - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppLayout()); - } -} - -class AppLayout extends StatelessWidget { - const AppLayout({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [ - SizedBox( - width: 210, - child: MenuPanel(), - ), - // Container() - Expanded(child: RootContent()) - ], - ), - // appBar: AppToolBar(), - // body: AppNavigation(), - ); - } -} - -class MenuPanel extends StatefulWidget { - const MenuPanel({super.key}); - - @override - State createState() => _MenuPanelState(); -} - -class _MenuPanelState extends State { - MenuState state = MenuState(expandMenus: ['/dashboard'], activeMenu: '/dashboard/data_analyse', items: menus); - - @override - Widget build(BuildContext context) { - return TolyMenu(state: state, onSelect: _onSelect); - } - - void _onSelect(MenuData menu) { - - - if(menu.isLeaf){ - state = state.copyWith(activeMenu: menu.path); - print("menu.path:${menu.path}"); - goRouter.go(menu.path); - }else{ - List menus = []; - String path = menu.path.substring(1); - List parts = path.split('/'); - - if(parts.isNotEmpty){ - String path = ''; - for (String part in parts) { - path+='/$part'; - menus.add(path); - } - } - - if(state.expandMenus.contains(menu.path)){ - menus.remove(menu.path); - } - - state = state.copyWith(expandMenus: menus); - - } - setState(() { - - }); - } -} diff --git a/lib/13/02_/pages/app/root_content.dart b/lib/13/02_/pages/app/root_content.dart deleted file mode 100644 index a7d78cc..0000000 --- a/lib/13/02_/pages/app/root_content.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/cases/cases.dart'; - -import '../color_page.dart'; - -// GoRouter configuration -final goRouter = GoRouter( - initialLocation: '/manager', - routes: [ - GoRoute( - path: '/dashboard', - builder: (_,__)=>SizedBox(), - routes: [ - GoRoute( - path: 'data_analyse', - // builder: (context, state) => ColorPage(title: 'data_analyse',), - pageBuilder: (context, state) { - return CustomTransitionPage( - key: state.pageKey, - child: ColorPage(title: 'data_analyse',), - transitionsBuilder: (context, animation, secondaryAnimation, child) { - // Change the opacity of the screen using a Curve based on the the animation's - // value - return FadeTransition( - opacity: - CurveTween(curve: Curves.easeInOutCirc).animate(animation), - child: child, - ); - }, - ); - }, - ), - - GoRoute( - path: 'work_board', - builder: (_,__)=>SizedBox(), - routes: [ - GoRoute( - path: 'a', - builder: (context, state) => ColorPage(title: '第一工作区',), - ), - GoRoute( - path: 'b', - builder: (context, state) => ColorPage(title: '第二工作区',), - ), - GoRoute( - path: 'c', - builder: (context, state) => ColorPage(title: '第三工作区',), - ), - ] - ), - - ] - ), - - GoRoute( - path: '/cases', - builder: (_,__)=>SizedBox(), - routes: [ - GoRoute( - path: 'counter', - builder: (context, state) => CounterPage(), - ), - GoRoute( - path: 'guess', - builder: (context, state) => GuessPage(), - ), - GoRoute( - path: 'muyu', - builder: (context, state) => ColorPage(title: '第三工作区',), - ), GoRoute( - path: 'canvas', - builder: (context, state) => Paper(), - ), GoRoute( - path: 'muyu', - builder: (context, state) => ColorPage(title: '第三工作区',), - ), - ] - ), - GoRoute( - path: '/manager', builder: (_,__)=>SizedBox(), - routes: [ - GoRoute( - path: 'account', - builder: (context, state) => ColorPage(title: 'account',), - ), - GoRoute( - path: 'role', - builder: (context, state) => ColorPage(title: 'role',), - ), - ] - ), - ], -); - - -class RootContent extends StatelessWidget { - const RootContent({super.key}); - - @override - Widget build(BuildContext context) { - - - return Router.withConfig(config: goRouter); - } -} - -class RootContentDelegate extends RouterDelegate with ChangeNotifier,PopNavigatorRouterDelegateMixin{ - - - @override - final GlobalKey navigatorKey = GlobalKey(); - - - @override - Widget build(BuildContext context) { - return Navigator( - key: navigatorKey, - pages: [ - - ], - onPopPage: (route, result) { - // appState.selectedBook = null; - // notifyListeners(); - return route.didPop(result); - }, - ); - } - - - @override - Future setNewRoutePath(configuration) { - // TODO: implement setNewRoutePath - throw UnimplementedError(); - } - - - -} \ No newline at end of file diff --git a/lib/13/02_/pages/color_page.dart b/lib/13/02_/pages/color_page.dart deleted file mode 100644 index 08449bb..0000000 --- a/lib/13/02_/pages/color_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPage extends StatelessWidget { - final String title; - const ColorPage({super.key, required this.title}); - - @override - Widget build(BuildContext context) { - return Scaffold(body: Center(child: Text(title))); - } -} diff --git a/lib/13/02_/transition/fade_transition.dart b/lib/13/02_/transition/fade_transition.dart deleted file mode 100644 index 751b9bb..0000000 --- a/lib/13/02_/transition/fade_transition.dart +++ /dev/null @@ -1,58 +0,0 @@ - - - - -import 'package:flutter/material.dart'; - - -class FadeTransitionsBuilder extends PageTransitionsBuilder { - /// Constructs a page transition animation that slides the page up. - const FadeTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation? secondaryAnimation, - Widget child, - ) { - return _FadeUpwardsPageTransition(routeAnimation: animation, child: child); - } -} - -class _FadeUpwardsPageTransition extends StatelessWidget { - _FadeUpwardsPageTransition({ - required Animation routeAnimation, // The route's linear 0.0 - 1.0 animation. - required this.child, - }) : _positionAnimation = routeAnimation.drive(_bottomUpTween.chain(_fastOutSlowInTween)), - _opacityAnimation = routeAnimation.drive(_easeInTween); - - // Fractional offset from 1/4 screen below the top to fully on screen. - static final Tween _bottomUpTween = Tween( - begin: const Offset(0.25,0), - end: Offset.zero, - ); - static final Animatable _fastOutSlowInTween = CurveTween(curve: Curves.fastOutSlowIn); - static final Animatable _easeInTween = CurveTween(curve: Curves.easeIn); - - final Animation _positionAnimation; - final Animation _opacityAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - // return FadeTransition( - // opacity: _opacityAnimation, - // child: child, - // ); - - return SlideTransition( - position: _positionAnimation, - child: FadeTransition( - opacity: _opacityAnimation, - child: child, - ), - ); - } -} \ No newline at end of file diff --git a/lib/13/02__/main.dart b/lib/13/02__/main.dart deleted file mode 100644 index 75b32c0..0000000 --- a/lib/13/02__/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index bb1d39b..0000000 --- a/lib/13/02__/pages/app.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import '../store/app_state.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 AppState _appState; - late final RouteState _routeState; - - @override - void initState() { - super.initState(); - _parser = AppRouteParser(initialRoute: '/color', allowPaths: [ - '/color', - '/color/add', - '/color/detail/:colorHex', - ]); - _appState = AppState.initial(); - _routeState = RouteState(_parser); - _delegate = RootRouterDelegate(_routeState); - } - - @override - Widget build(BuildContext context) { - return AppStateScope( - notifier: _appState, - child: 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/02__/pages/color_add_page.dart deleted file mode 100644 index bee43b4..0000000 --- a/lib/13/02__/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 7dd4549..0000000 --- a/lib/13/02__/pages/home_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import '../store/app_state.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 { - - - @override - Widget build(BuildContext context) { - AppState state = AppStateScope.of(context); - return Scaffold( - appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: ColorsPanel( - colors: state.colors, - onSelect: _selectColor, - ), - ); - } - - void _selectColor(Color color){ - String value = '#${color.value.toRadixString(16)}'; - RouteStateScope.of(context).update('/color/detail/$value'); - } - - void _toAddPage() async { - RouteStateScope.of(context).update('/color/add'); - } -} diff --git a/lib/13/02__/route/parsed_route.dart b/lib/13/02__/route/parsed_route.dart deleted file mode 100644 index 778d667..0000000 --- a/lib/13/02__/route/parsed_route.dart +++ /dev/null @@ -1,49 +0,0 @@ -// 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:quiver/core.dart'; - -/// A route path that has been parsed by [TemplateRouteParser]. -class ParsedRoute { - /// The current path location without query parameters. (/book/123) - final String path; - - /// The path template (/book/:id) - final String pathTemplate; - - /// The path parameters ({id: 123}) - final Map parameters; - - /// The query parameters ({search: abc}) - final Map queryParameters; - - static const _mapEquality = MapEquality(); - - ParsedRoute( - this.path, this.pathTemplate, this.parameters, this.queryParameters); - - @override - bool operator ==(Object other) => - other is ParsedRoute && - other.pathTemplate == pathTemplate && - other.path == path && - _mapEquality.equals(parameters, other.parameters) && - _mapEquality.equals(queryParameters, other.queryParameters); - - @override - int get hashCode => hash4( - path, - pathTemplate, - _mapEquality.hash(parameters), - _mapEquality.hash(queryParameters), - ); - - @override - String toString() => ''; -} diff --git a/lib/13/02__/route/parser.dart b/lib/13/02__/route/parser.dart deleted file mode 100644 index f27a266..0000000 --- a/lib/13/02__/route/parser.dart +++ /dev/null @@ -1,153 +0,0 @@ -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 '../store/app_state.dart'; -import 'parsed_route.dart'; -import 'route_state.dart'; - -class AppRouteParser extends RouteInformationParser { - final List allowPaths; - final ParsedRoute initialRoute; - - AppRouteParser({ - required this.allowPaths, - String initialRoute = '/', - }) : initialRoute = ParsedRoute(initialRoute, initialRoute, {}, {}); - - @override - Future parseRouteInformation( - RouteInformation routeInformation) async { - print( - "=======parseRouteInformation:${routeInformation.uri.path}==================="); - - final uri = routeInformation.uri; - final path = uri.toString(); - final queryParams = uri.queryParameters; - - ParsedRoute parsedRoute = initialRoute; - - for (var pathTemplate in allowPaths) { - final parameters = []; - var pathRegExp = pathToRegExp(pathTemplate, parameters: parameters); - if (pathRegExp.hasMatch(path)) { - final match = pathRegExp.matchAsPrefix(path); - if (match == null) continue; - final params = extract(parameters, match); - parsedRoute = ParsedRoute(path, pathTemplate, params, queryParams); - } - } - return parsedRoute; - } - - @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'); - final _detailColorKey = const ValueKey('detailColor'); - - @override - Widget build(BuildContext context) { - final routeState = RouteStateScope.of(context); - List pages = []; - final String pathTemplate = routeState.route.pathTemplate; - - pages.add(MaterialPage(child: HomePage())); - - String? selectedColor; - - if (pathTemplate == '/color/detail/:colorHex') { - selectedColor = routeState.route.parameters['colorHex']; - } - - if (selectedColor != null) { - int value = int.parse( - selectedColor.substring( - 1, - ), - radix: 16); - pages.add(MaterialPage( - key: _detailColorKey, - child: StlColorPage( - color: Color(value), - ))); - } - - bool isAddPage = pathTemplate == '/color/add'; - if (isAddPage) { - pages.add( - MaterialPage(key: _addColorKey, child: ColorAddPage()), - ); - } - print("===build===================="); - return Navigator( - key: navigatorKey, - pages: pages, - onPopPage: (route, result) { - print(result); - if (route.settings is Page && - (route.settings as Page).key == _addColorKey) { - if(result is Color){ - AppStateScope.of(context).addColor(result); - } - routeState.update('/color'); - } - - if (route.settings is Page && - (route.settings as Page).key == _detailColorKey) { - routeState.update('/color'); - } - // appState.selectedBook = null; - // notifyListeners(); - 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/02__/route/route_state.dart b/lib/13/02__/route/route_state.dart deleted file mode 100644 index a2ef01a..0000000 --- a/lib/13/02__/route/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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) : _route = _parser.initialRoute; - - 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 update(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/02__/store/app_state.dart b/lib/13/02__/store/app_state.dart deleted file mode 100644 index 57d820f..0000000 --- a/lib/13/02__/store/app_state.dart +++ /dev/null @@ -1,32 +0,0 @@ - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class AppState extends ChangeNotifier{ - final List colors; - - AppState({required this.colors,}); - - AppState.initial():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, - ]; - - void addColor(Color color){ - colors.add(color); - notifyListeners(); - } - -} - -/// Provides the current [RouteState] to descendant widgets in the tree. -class AppStateScope extends InheritedNotifier { - const AppStateScope({super.key, required super.child, required super.notifier,}); - - - - static AppState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; -} diff --git a/lib/13/03/main.dart b/lib/13/03/main.dart deleted file mode 100644 index 38c9d78..0000000 --- a/lib/13/03/main.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app/unit_app.dart'; -import 'app/navigation/app_router_delegate.dart'; - - - - - -void main() { - runApp(const UnitApp()); -} - - - - diff --git a/lib/13/03_/main.dart b/lib/13/03_/main.dart deleted file mode 100644 index 881b6ec..0000000 --- a/lib/13/03_/main.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'pages/app/app.dart'; - - - -void main() { - runApp(const App()); -} - - - - diff --git a/lib/13/03_/menus.dart b/lib/13/03_/menus.dart deleted file mode 100644 index 1aa20cb..0000000 --- a/lib/13/03_/menus.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:toly_menu/toly_menu.dart'; - -List menus = [ - MenuData(path: '/dashboard', label: '总览面板', children: [ - MenuData(path: '/dashboard/data_analyse', label: '数据分析', deep: 1), - MenuData(path: '/dashboard/work_board', label: '工作台', deep: 1, children: [ - MenuData(path: '/dashboard/work_board/a', label: '第一工作区', deep: 2), - MenuData(path: '/dashboard/work_board/b', label: '第二工作区', deep: 2), - MenuData(path: '/dashboard/work_board/c', label: '第三工作区', deep: 2), - ]), - ]), - MenuData(path: '/manager', label: '系统管理', children: [ - MenuData(path: '/manager/account', label: '账号管理', deep: 1), - MenuData(path: '/manager/role', label: '角色管理', deep: 1), - MenuData(path: '/manager/menu', label: '菜单管理', deep: 1), - ]), - MenuData(path: '/knowledge', label: '知识库管理', children: [ - MenuData(path: '/knowledge/a', label: '语文知识', deep: 1, children: [ - MenuData( - path: '/knowledge/a/1', - label: '诗词歌赋', - deep: 2, - ), - MenuData( - path: '/knowledge/a/2', - label: '人物故事', - deep: 2, - ), - MenuData( - path: '/knowledge/a/3', - label: '名著推荐', - deep: 2, - ) - ]), - MenuData( - path: '/knowledge/b', - label: '数学知识', - children: [ - MenuData( - path: '/knowledge/b/1', - label: '人物故事', - deep: 2, - ), - MenuData( - path: '/knowledge/b/2', - label: '数学定理', - deep: 2, - ), - MenuData( - path: '/knowledge/b/3', - label: '几何知识', - deep: 2, - ), - MenuData( - path: '/knowledge/b/4', - label: '代数知识', - deep: 2, - ) - ], - deep: 1), - MenuData( - path: '/knowledge/c', - label: '英语知识', - deep: 1, - ), - ]), - MenuData(path: '/widgets', label: '组件集录', children: [ - MenuData(path: '/widgets/stateless', label: '无状态组件', deep: 1), - MenuData(path: '/widgets/stateful', label: '有状态组件', deep: 1), - MenuData(path: '/widgets/single_child', label: '单子渲染组件', deep: 1), - MenuData(path: '/widgets/mutli_child', label: '多子渲染组件', deep: 1), - MenuData(path: '/widgets/sliver', label: '滑片组件', deep: 1), - MenuData(path: '/widgets/proxy', label: '代理组件', deep: 1), - MenuData(path: '/widgets/other', label: '其他组件', deep: 1), - ]) -]; diff --git a/lib/13/03_/pages/app/app.dart b/lib/13/03_/pages/app/app.dart deleted file mode 100644 index b6b3ac2..0000000 --- a/lib/13/03_/pages/app/app.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:toly_menu/toly_menu.dart'; - -import '../../menus.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: AppLayout()); - } -} - -class AppLayout extends StatelessWidget { - const AppLayout({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [ - SizedBox( - width: 210, - child: MenuPanel(), - ), - // Container() - ], - ), - // appBar: AppToolBar(), - // body: AppNavigation(), - ); - } -} - -class MenuPanel extends StatefulWidget { - const MenuPanel({super.key}); - - @override - State createState() => _MenuPanelState(); -} - -class _MenuPanelState extends State { - MenuState state = MenuState(expandMenus: ['/dashboard'], activeMenu: '/dashboard/data_analyse', items: menus); - - @override - Widget build(BuildContext context) { - return TolyMenu(state: state, onSelect: _onSelect); - } - - void _onSelect(MenuData menu) { - if(menu.isLeaf){ - state = state.copyWith(activeMenu: menu.path); - }else{ - List menus = []; - String path = menu.path.substring(1); - List parts = path.split('/'); - - if(parts.isNotEmpty){ - String path = ''; - for (String part in parts) { - path+='/$part'; - menus.add(path); - } - } - - if(state.expandMenus.contains(menu.path)){ - menus.remove(menu.path); - } - - state = state.copyWith(expandMenus: menus); - - } - setState(() { - - }); - } -} diff --git a/lib/13/03_/pages/app/root_content.dart b/lib/13/03_/pages/app/root_content.dart deleted file mode 100644 index 36c46b5..0000000 --- a/lib/13/03_/pages/app/root_content.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class RootContent extends StatelessWidget { - const RootContent({super.key}); - - @override - Widget build(BuildContext context) { - return Router(routerDelegate: RootContentDelegate()); - } -} - -class RootContentDelegate extends RouterDelegate with ChangeNotifier,PopNavigatorRouterDelegateMixin{ - - - @override - final GlobalKey navigatorKey = GlobalKey(); - - - @override - Widget build(BuildContext context) { - return Navigator( - key: navigatorKey, - pages: [ - - ], - onPopPage: (route, result) { - // appState.selectedBook = null; - // notifyListeners(); - return route.didPop(result); - }, - ); - } - - - @override - Future setNewRoutePath(configuration) { - // TODO: implement setNewRoutePath - throw UnimplementedError(); - } - - - -} \ No newline at end of file diff --git a/lib/13/04/app/navigation/app_router_delegate.dart b/lib/13/04/app/navigation/app_router_delegate.dart deleted file mode 100644 index 587f207..0000000 --- a/lib/13/04/app/navigation/app_router_delegate.dart +++ /dev/null @@ -1,208 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:iroute/13/04/app/navigation/router/iroute.dart'; -import 'package:iroute/common/pages/stl_color_page.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 kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate 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; - } - - final Map> _completerMap = {}; - - Completer? completer; - - Future changePathForResult(String value) async{ - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - // IRoute? parserPath(String path){ - // - // List parts = path.split('/'); - // String lever1 = '/${parts[1]}'; - // List iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList(); - // - // int counter = 2; - // - // IRoute? result; - // String check = lever1; - // for(int i = 0;i _buildPageByPath(String path) { - if(path.startsWith('/color')){ - return buildColorPages(path); - } - - Widget? child; - 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(), - ) - ]; - } - - List buildColorPages(String path){ - List result = []; - Uri uri = Uri.parse(path); - for (String segment in uri.pathSegments) { - if(segment == 'color'){ - result.add( const FadeTransitionPage( - key: ValueKey('/color'), - child:ColorPage(), - )); - } - if(segment =='detail'){ - final Map queryParams = uri.queryParameters; - String? selectedColor = queryParams['color']; - if (selectedColor != null) { - Color color = Color(int.parse(selectedColor, radix: 16)); - result.add( FadeTransitionPage( - key: const ValueKey('/color/detail'), - child:StlColorPage(color: color), - )); - } - } - if(segment == 'add'){ - result.add( const FadeTransitionPage( - key: ValueKey('/color/add'), - child:ColorAddPage(), - )); - } - - } - return result; - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - bool _onPopPage(Route route, result) { - if(_completerMap.containsKey(path)){ - _completerMap[path]?.complete(result); - _completerMap.remove(path); - } - - path = backPath(path); - return route.didPop(result); - } - - String backPath(String path){ - Uri uri = Uri.parse(path); - if(uri.pathSegments.length==1) return path; - List parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @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{ -// } -// } diff --git a/lib/13/04/main.dart b/lib/13/04/main.dart deleted file mode 100644 index 38c9d78..0000000 --- a/lib/13/04/main.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app/unit_app.dart'; -import 'app/navigation/app_router_delegate.dart'; - - - - - -void main() { - runApp(const UnitApp()); -} - - - - diff --git a/lib/13/04/pages/empty/empty_page.dart b/lib/13/04/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/13/04/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -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), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/13/go/async_redirection.dart b/lib/13/go/async_redirection.dart deleted file mode 100644 index f84c14e..0000000 --- a/lib/13/go/async_redirection.dart +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -// This scenario demonstrates how to use redirect to handle a asynchronous -// sign-in flow. -// -// The `StreamAuth` is a mock of google_sign_in. This example wraps it with an -// InheritedNotifier, StreamAuthScope, and relies on -// `dependOnInheritedWidgetOfExactType` to create a dependency between the -// notifier and go_router's parsing pipeline. When StreamAuth broadcasts new -// event, the dependency will cause the go_router to reparse the current url -// which will also trigger the redirect. - -void main() => runApp(StreamAuthScope(child: App())); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Redirection'; - - // add the login info into the tree as app state that can change over time - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - debugShowCheckedModeBanner: false, - ); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const HomeScreen(), - ), - GoRoute( - path: '/login', - builder: (BuildContext context, GoRouterState state) => - const LoginScreen(), - ), - ], - - // redirect to the login page if the user is not logged in - redirect: (BuildContext context, GoRouterState state) async { - // Using `of` method creates a dependency of StreamAuthScope. It will - // cause go_router to reparse current route if StreamAuth has new sign-in - // information. - final bool loggedIn = await StreamAuthScope.of(context).isSignedIn(); - final bool loggingIn = state.matchedLocation == '/login'; - if (!loggedIn) { - return '/login'; - } - - // if the user is logged in but still on the login page, send them to - // the home page - if (loggingIn) { - return '/'; - } - - // no need to redirect at all - return null; - }, - ); -} - -/// The login screen. -class LoginScreen extends StatefulWidget { - /// Creates a [LoginScreen]. - const LoginScreen({super.key}); - - @override - State createState() => _LoginScreenState(); -} - -class _LoginScreenState extends State - with TickerProviderStateMixin { - bool loggingIn = false; - late final AnimationController controller; - - @override - void initState() { - super.initState(); - controller = AnimationController( - vsync: this, - duration: const Duration(seconds: 1), - )..addListener(() { - setState(() {}); - }); - controller.repeat(); - } - - @override - void dispose() { - controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (loggingIn) CircularProgressIndicator(value: controller.value), - if (!loggingIn) - ElevatedButton( - onPressed: () { - StreamAuthScope.of(context).signIn('test-user'); - setState(() { - loggingIn = true; - }); - }, - child: const Text('Login'), - ), - ], - ), - ), - ); -} - -/// The home screen. -class HomeScreen extends StatelessWidget { - /// Creates a [HomeScreen]. - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - final StreamAuth info = StreamAuthScope.of(context); - - return Scaffold( - appBar: AppBar( - title: const Text(App.title), - actions: [ - IconButton( - onPressed: () => info.signOut(), - tooltip: 'Logout: ${info.currentUser}', - icon: const Icon(Icons.logout), - ) - ], - ), - body: const Center( - child: Text('HomeScreen'), - ), - ); - } -} - -/// A scope that provides [StreamAuth] for the subtree. -class StreamAuthScope extends InheritedNotifier { - /// Creates a [StreamAuthScope] sign in scope. - StreamAuthScope({ - super.key, - required super.child, - }) : super( - notifier: StreamAuthNotifier(), - ); - - /// Gets the [StreamAuth]. - static StreamAuth of(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType()! - .notifier! - .streamAuth; - } -} - -/// A class that converts [StreamAuth] into a [ChangeNotifier]. -class StreamAuthNotifier extends ChangeNotifier { - /// Creates a [StreamAuthNotifier]. - StreamAuthNotifier() : streamAuth = StreamAuth() { - streamAuth.onCurrentUserChanged.listen((String? string) { - notifyListeners(); - }); - } - - /// The stream auth client. - final StreamAuth streamAuth; -} - -/// An asynchronous log in services mock with stream similar to google_sign_in. -/// -/// This class adds an artificial delay of 3 second when logging in an user, and -/// will automatically clear the login session after [refreshInterval]. -class StreamAuth { - /// Creates an [StreamAuth] that clear the current user session in - /// [refeshInterval] second. - StreamAuth({this.refreshInterval = 20}) - : _userStreamController = StreamController.broadcast() { - _userStreamController.stream.listen((String? currentUser) { - _currentUser = currentUser; - }); - } - - /// The current user. - String? get currentUser => _currentUser; - String? _currentUser; - - /// Checks whether current user is signed in with an artificial delay to mimic - /// async operation. - Future isSignedIn() async { - await Future.delayed(const Duration(seconds: 1)); - return _currentUser != null; - } - - /// A stream that notifies when current user has changed. - Stream get onCurrentUserChanged => _userStreamController.stream; - final StreamController _userStreamController; - - /// The interval that automatically signs out the user. - final int refreshInterval; - - Timer? _timer; - Timer _createRefreshTimer() { - return Timer(Duration(seconds: refreshInterval), () { - _userStreamController.add(null); - _timer = null; - }); - } - - /// Signs in a user with an artificial delay to mimic async operation. - Future signIn(String newUserName) async { - await Future.delayed(const Duration(seconds: 3)); - _userStreamController.add(newUserName); - _timer?.cancel(); - _timer = _createRefreshTimer(); - } - - /// Signs out the current user. - Future signOut() async { - _timer?.cancel(); - _timer = null; - _userStreamController.add(null); - } -} diff --git a/lib/13/go/books/main.dart b/lib/13/go/books/main.dart deleted file mode 100644 index eb757e3..0000000 --- a/lib/13/go/books/main.dart +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -import 'src/auth.dart'; -import 'src/data/author.dart'; -import 'src/data/book.dart'; -import 'src/data/library.dart'; -import 'src/screens/author_details.dart'; -import 'src/screens/authors.dart'; -import 'src/screens/book_details.dart'; -import 'src/screens/books.dart'; -import 'src/screens/scaffold.dart'; -import 'src/screens/settings.dart'; -import 'src/screens/sign_in.dart'; - -void main() => runApp(Bookstore()); - -/// The book store view. -class Bookstore extends StatelessWidget { - /// Creates a [Bookstore]. - Bookstore({super.key}); - - final ValueKey _scaffoldKey = const ValueKey('App scaffold'); - - @override - Widget build(BuildContext context) => BookstoreAuthScope( - notifier: _auth, - child: MaterialApp.router( - routerConfig: _router, - ), - ); - - final BookstoreAuth _auth = BookstoreAuth(); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - redirect: (_, __) => '/books', - ), - GoRoute( - path: '/signin', - pageBuilder: (BuildContext context, GoRouterState state) => - FadeTransitionPage( - key: state.pageKey, - child: SignInScreen( - onSignIn: (Credentials credentials) { - BookstoreAuthScope.of(context) - .signIn(credentials.username, credentials.password); - }, - ), - ), - ), - GoRoute( - path: '/books', - redirect: (_, __) => '/books/popular', - ), - GoRoute( - path: '/book/:bookId', - redirect: (BuildContext context, GoRouterState state) => - '/books/all/${state.pathParameters['bookId']}', - ), - GoRoute( - path: '/books/:kind(new|all|popular)', - pageBuilder: (BuildContext context, GoRouterState state) => - FadeTransitionPage( - key: _scaffoldKey, - child: BookstoreScaffold( - selectedTab: ScaffoldTab.books, - child: BooksScreen(state.pathParameters['kind']!), - ), - ), - routes: [ - GoRoute( - path: ':bookId', - builder: (BuildContext context, GoRouterState state) { - final String bookId = state.pathParameters['bookId']!; - final Book? selectedBook = libraryInstance.allBooks - .firstWhereOrNull((Book b) => b.id.toString() == bookId); - - return BookDetailsScreen(book: selectedBook); - }, - ), - ], - ), - GoRoute( - path: '/author/:authorId', - redirect: (BuildContext context, GoRouterState state) => - '/authors/${state.pathParameters['authorId']}', - ), - GoRoute( - path: '/authors', - pageBuilder: (BuildContext context, GoRouterState state) => - FadeTransitionPage( - key: _scaffoldKey, - child: const BookstoreScaffold( - selectedTab: ScaffoldTab.authors, - child: AuthorsScreen(), - ), - ), - routes: [ - GoRoute( - path: ':authorId', - builder: (BuildContext context, GoRouterState state) { - final int authorId = int.parse(state.pathParameters['authorId']!); - final Author? selectedAuthor = libraryInstance.allAuthors - .firstWhereOrNull((Author a) => a.id == authorId); - - return AuthorDetailsScreen(author: selectedAuthor); - }, - ), - ], - ), - GoRoute( - path: '/settings', - pageBuilder: (BuildContext context, GoRouterState state) => - FadeTransitionPage( - key: _scaffoldKey, - child: const BookstoreScaffold( - selectedTab: ScaffoldTab.settings, - child: SettingsScreen(), - ), - ), - ), - ], - redirect: _guard, - refreshListenable: _auth, - debugLogDiagnostics: true, - ); - - String? _guard(BuildContext context, GoRouterState state) { - final bool signedIn = _auth.signedIn; - final bool signingIn = state.matchedLocation == '/signin'; - - // Go to /signin if the user is not signed in - if (!signedIn && !signingIn) { - return '/signin'; - } - // Go to /books if the user is signed in and tries to go to /signin. - else if (signedIn && signingIn) { - return '/books'; - } - - // no redirect - return null; - } -} - -/// A page that fades in an out. -class FadeTransitionPage extends CustomTransitionPage { - /// Creates a [FadeTransitionPage]. - FadeTransitionPage({ - required LocalKey super.key, - required super.child, - }) : super( - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) => - FadeTransition( - opacity: animation.drive(_curveTween), - child: child, - )); - - static final CurveTween _curveTween = CurveTween(curve: Curves.easeIn); -} diff --git a/lib/13/go/books/src/auth.dart b/lib/13/go/books/src/auth.dart deleted file mode 100644 index b9c353c..0000000 --- a/lib/13/go/books/src/auth.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; - -/// A mock authentication service. -class BookstoreAuth extends ChangeNotifier { - bool _signedIn = false; - - /// Whether user has signed in. - bool get signedIn => _signedIn; - - /// Signs out the current user. - Future signOut() async { - await Future.delayed(const Duration(milliseconds: 200)); - // Sign out. - _signedIn = false; - notifyListeners(); - } - - /// Signs in a user. - Future signIn(String username, String password) async { - await Future.delayed(const Duration(milliseconds: 200)); - - // Sign in. Allow any password. - _signedIn = true; - notifyListeners(); - return _signedIn; - } -} - -/// An inherited notifier to host [BookstoreAuth] for the subtree. -class BookstoreAuthScope extends InheritedNotifier { - /// Creates a [BookstoreAuthScope]. - const BookstoreAuthScope({ - required BookstoreAuth super.notifier, - required super.child, - super.key, - }); - - /// Gets the [BookstoreAuth] above the context. - static BookstoreAuth of(BuildContext context) => context - .dependOnInheritedWidgetOfExactType()! - .notifier!; -} diff --git a/lib/13/go/books/src/data.dart b/lib/13/go/books/src/data.dart deleted file mode 100644 index 109082e..0000000 --- a/lib/13/go/books/src/data.dart +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -export 'data/author.dart'; -export 'data/book.dart'; -export 'data/library.dart'; diff --git a/lib/13/go/books/src/data/author.dart b/lib/13/go/books/src/data/author.dart deleted file mode 100644 index b58db11..0000000 --- a/lib/13/go/books/src/data/author.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'book.dart'; - -/// Author data class. -class Author { - /// Creates an author data object. - Author({ - required this.id, - required this.name, - }); - - /// The id of the author. - final int id; - - /// The name of the author. - final String name; - - /// The books of the author. - final List books = []; -} diff --git a/lib/13/go/books/src/data/book.dart b/lib/13/go/books/src/data/book.dart deleted file mode 100644 index cd2c94f..0000000 --- a/lib/13/go/books/src/data/book.dart +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'author.dart'; - -/// Book data class. -class Book { - /// Creates a book data object. - Book({ - required this.id, - required this.title, - required this.isPopular, - required this.isNew, - required this.author, - }); - - /// The id of the book. - final int id; - - /// The title of the book. - final String title; - - /// The author of the book. - final Author author; - - /// Whether the book is popular. - final bool isPopular; - - /// Whether the book is new. - final bool isNew; -} diff --git a/lib/13/go/books/src/data/library.dart b/lib/13/go/books/src/data/library.dart deleted file mode 100644 index 075b825..0000000 --- a/lib/13/go/books/src/data/library.dart +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'author.dart'; -import 'book.dart'; - -/// Library data mock. -final Library libraryInstance = Library() - ..addBook( - title: 'Left Hand of Darkness', - authorName: 'Ursula K. Le Guin', - isPopular: true, - isNew: true) - ..addBook( - title: 'Too Like the Lightning', - authorName: 'Ada Palmer', - isPopular: false, - isNew: true) - ..addBook( - title: 'Kindred', - authorName: 'Octavia E. Butler', - isPopular: true, - isNew: false) - ..addBook( - title: 'The Lathe of Heaven', - authorName: 'Ursula K. Le Guin', - isPopular: false, - isNew: false); - -/// A library that contains books and authors. -class Library { - /// The books in the library. - final List allBooks = []; - - /// The authors in the library. - final List allAuthors = []; - - /// Adds a book into the library. - void addBook({ - required String title, - required String authorName, - required bool isPopular, - required bool isNew, - }) { - final Author author = allAuthors.firstWhere( - (Author author) => author.name == authorName, - orElse: () { - final Author value = Author(id: allAuthors.length, name: authorName); - allAuthors.add(value); - return value; - }, - ); - - final Book book = Book( - id: allBooks.length, - title: title, - isPopular: isPopular, - isNew: isNew, - author: author, - ); - - author.books.add(book); - allBooks.add(book); - } - - /// The list of popular books in the library. - List get popularBooks => [ - ...allBooks.where((Book book) => book.isPopular), - ]; - - /// The list of new books in the library. - List get newBooks => [ - ...allBooks.where((Book book) => book.isNew), - ]; -} diff --git a/lib/13/go/books/src/screens/author_details.dart b/lib/13/go/books/src/screens/author_details.dart deleted file mode 100644 index 3aff898..0000000 --- a/lib/13/go/books/src/screens/author_details.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -import '../data.dart'; -import '../widgets/book_list.dart'; - -/// The author detail screen. -class AuthorDetailsScreen extends StatelessWidget { - /// Creates an author detail screen. - const AuthorDetailsScreen({ - required this.author, - super.key, - }); - - /// The author to be displayed. - final Author? author; - - @override - Widget build(BuildContext context) { - if (author == null) { - return const Scaffold( - body: Center( - child: Text('No author found.'), - ), - ); - } - return Scaffold( - appBar: AppBar( - title: Text(author!.name), - ), - body: Center( - child: Column( - children: [ - Expanded( - child: BookList( - books: author!.books, - onTap: (Book book) => context.go('/book/${book.id}'), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/13/go/books/src/screens/authors.dart b/lib/13/go/books/src/screens/authors.dart deleted file mode 100644 index 0eeb1c3..0000000 --- a/lib/13/go/books/src/screens/authors.dart +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -import '../data.dart'; -import '../widgets/author_list.dart'; - -/// A screen that displays a list of authors. -class AuthorsScreen extends StatelessWidget { - /// Creates an [AuthorsScreen]. - const AuthorsScreen({super.key}); - - /// The title of the screen. - static const String title = 'Authors'; - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text(title), - ), - body: AuthorList( - authors: libraryInstance.allAuthors, - onTap: (Author author) { - context.go('/author/${author.id}'); - }, - ), - ); -} diff --git a/lib/13/go/books/src/screens/book_details.dart b/lib/13/go/books/src/screens/book_details.dart deleted file mode 100644 index 9a51a83..0000000 --- a/lib/13/go/books/src/screens/book_details.dart +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; -import 'package:url_launcher/link.dart'; - -import '../data.dart'; -import 'author_details.dart'; - -/// A screen to display book details. -class BookDetailsScreen extends StatelessWidget { - /// Creates a [BookDetailsScreen]. - const BookDetailsScreen({ - super.key, - this.book, - }); - - /// The book to be displayed. - final Book? book; - - @override - Widget build(BuildContext context) { - if (book == null) { - return const Scaffold( - body: Center( - child: Text('No book found.'), - ), - ); - } - return Scaffold( - appBar: AppBar( - title: Text(book!.title), - ), - body: Center( - child: Column( - children: [ - Text( - book!.title, - style: Theme.of(context).textTheme.headlineMedium, - ), - Text( - book!.author.name, - style: Theme.of(context).textTheme.titleMedium, - ), - TextButton( - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => - AuthorDetailsScreen(author: book!.author), - ), - ); - }, - child: const Text('View author (navigator.push)'), - ), - Link( - uri: Uri.parse('/author/${book!.author.id}'), - builder: (BuildContext context, FollowLink? followLink) => - TextButton( - onPressed: followLink, - child: const Text('View author (Link)'), - ), - ), - TextButton( - onPressed: () { - context.push('/author/${book!.author.id}'); - }, - child: const Text('View author (GoRouter.push)'), - ), - ], - ), - ), - ); - } -} diff --git a/lib/13/go/books/src/screens/books.dart b/lib/13/go/books/src/screens/books.dart deleted file mode 100644 index b0e7ca2..0000000 --- a/lib/13/go/books/src/screens/books.dart +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -import '../data.dart'; -import '../widgets/book_list.dart'; - -/// A screen that displays a list of books. -class BooksScreen extends StatefulWidget { - /// Creates a [BooksScreen]. - const BooksScreen(this.kind, {super.key}); - - /// Which tab to display. - final String kind; - - @override - State createState() => _BooksScreenState(); -} - -class _BooksScreenState extends State - with SingleTickerProviderStateMixin { - late TabController _tabController; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 3, vsync: this); - } - - @override - void didUpdateWidget(BooksScreen oldWidget) { - super.didUpdateWidget(oldWidget); - - switch (widget.kind) { - case 'popular': - _tabController.index = 0; - break; - - case 'new': - _tabController.index = 1; - break; - - case 'all': - _tabController.index = 2; - break; - } - } - - @override - void dispose() { - _tabController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text('Books'), - bottom: TabBar( - controller: _tabController, - onTap: _handleTabTapped, - tabs: const [ - Tab( - text: 'Popular', - icon: Icon(Icons.people), - ), - Tab( - text: 'New', - icon: Icon(Icons.new_releases), - ), - Tab( - text: 'All', - icon: Icon(Icons.list), - ), - ], - ), - ), - body: TabBarView( - controller: _tabController, - children: [ - BookList( - books: libraryInstance.popularBooks, - onTap: _handleBookTapped, - ), - BookList( - books: libraryInstance.newBooks, - onTap: _handleBookTapped, - ), - BookList( - books: libraryInstance.allBooks, - onTap: _handleBookTapped, - ), - ], - ), - ); - - void _handleBookTapped(Book book) { - context.go('/book/${book.id}'); - } - - void _handleTabTapped(int index) { - switch (index) { - case 1: - context.go('/books/new'); - break; - case 2: - context.go('/books/all'); - break; - case 0: - default: - context.go('/books/popular'); - break; - } - } -} diff --git a/lib/13/go/books/src/screens/scaffold.dart b/lib/13/go/books/src/screens/scaffold.dart deleted file mode 100644 index 2ffaf9a..0000000 --- a/lib/13/go/books/src/screens/scaffold.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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:adaptive_navigation/adaptive_navigation.dart'; -import 'package:flutter/material.dart'; - -import 'package:go_router/go_router.dart'; - -/// The enum for scaffold tab. -enum ScaffoldTab { - /// The books tab. - books, - - /// The authors tab. - authors, - - /// The settings tab. - settings -} - -/// The scaffold for the book store. -class BookstoreScaffold extends StatelessWidget { - /// Creates a [BookstoreScaffold]. - const BookstoreScaffold({ - required this.selectedTab, - required this.child, - super.key, - }); - - /// Which tab of the scaffold to display. - final ScaffoldTab selectedTab; - - /// The scaffold body. - final Widget child; - - @override - Widget build(BuildContext context) => Scaffold( - body: AdaptiveNavigationScaffold( - selectedIndex: selectedTab.index, - body: child, - onDestinationSelected: (int idx) { - switch (ScaffoldTab.values[idx]) { - case ScaffoldTab.books: - context.go('/books'); - break; - case ScaffoldTab.authors: - context.go('/authors'); - break; - case ScaffoldTab.settings: - context.go('/settings'); - break; - } - }, - destinations: const [ - AdaptiveScaffoldDestination( - title: 'Books', - icon: Icons.book, - ), - AdaptiveScaffoldDestination( - title: 'Authors', - icon: Icons.person, - ), - AdaptiveScaffoldDestination( - title: 'Settings', - icon: Icons.settings, - ), - ], - ), - ); -} diff --git a/lib/13/go/books/src/screens/settings.dart b/lib/13/go/books/src/screens/settings.dart deleted file mode 100644 index a098e30..0000000 --- a/lib/13/go/books/src/screens/settings.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; -import 'package:url_launcher/link.dart'; - -import '../auth.dart'; - -/// The settings screen. -class SettingsScreen extends StatefulWidget { - /// Creates a [SettingsScreen]. - const SettingsScreen({super.key}); - - @override - State createState() => _SettingsScreenState(); -} - -class _SettingsScreenState extends State { - @override - Widget build(BuildContext context) => Scaffold( - body: SafeArea( - child: SingleChildScrollView( - child: Align( - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 400), - child: const Card( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12), - child: SettingsContent(), - ), - ), - ), - ), - ), - ), - ); -} - -/// The content of a [SettingsScreen]. -class SettingsContent extends StatelessWidget { - /// Creates a [SettingsContent]. - const SettingsContent({ - super.key, - }); - - @override - Widget build(BuildContext context) => Column( - children: [ - ...[ - Text( - 'Settings', - style: Theme.of(context).textTheme.headlineMedium, - ), - ElevatedButton( - onPressed: () { - BookstoreAuthScope.of(context).signOut(); - }, - child: const Text('Sign out'), - ), - Link( - uri: Uri.parse('/book/0'), - builder: (BuildContext context, FollowLink? followLink) => - TextButton( - onPressed: followLink, - child: const Text('Go directly to /book/0 (Link)'), - ), - ), - TextButton( - onPressed: () { - context.go('/book/0'); - }, - child: const Text('Go directly to /book/0 (GoRouter)'), - ), - ].map((Widget w) => - Padding(padding: const EdgeInsets.all(8), child: w)), - TextButton( - onPressed: () => showDialog( - context: context, - builder: (BuildContext context) => AlertDialog( - title: const Text('Alert!'), - content: const Text('The alert description goes here.'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, 'Cancel'), - child: const Text('Cancel'), - ), - TextButton( - onPressed: () => Navigator.pop(context, 'OK'), - child: const Text('OK'), - ), - ], - ), - ), - child: const Text('Show Dialog'), - ) - ], - ); -} diff --git a/lib/13/go/books/src/screens/sign_in.dart b/lib/13/go/books/src/screens/sign_in.dart deleted file mode 100644 index e02c870..0000000 --- a/lib/13/go/books/src/screens/sign_in.dart +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; - -/// Credential data class. -class Credentials { - /// Creates a credential data object. - Credentials(this.username, this.password); - - /// The username of the credentials. - final String username; - - /// The password of the credentials. - final String password; -} - -/// The sign-in screen. -class SignInScreen extends StatefulWidget { - /// Creates a sign-in screen. - const SignInScreen({ - required this.onSignIn, - super.key, - }); - - /// Called when users sign in with [Credentials]. - final ValueChanged onSignIn; - - @override - State createState() => _SignInScreenState(); -} - -class _SignInScreenState extends State { - final TextEditingController _usernameController = TextEditingController(); - final TextEditingController _passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) => Scaffold( - body: Center( - child: Card( - child: Container( - constraints: BoxConstraints.loose(const Size(600, 600)), - padding: const EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text('Sign in', - style: Theme.of(context).textTheme.headlineMedium), - TextField( - decoration: const InputDecoration(labelText: 'Username'), - controller: _usernameController, - ), - TextField( - decoration: const InputDecoration(labelText: 'Password'), - obscureText: true, - controller: _passwordController, - ), - Padding( - padding: const EdgeInsets.all(16), - child: TextButton( - onPressed: () async { - widget.onSignIn(Credentials( - _usernameController.value.text, - _passwordController.value.text)); - }, - child: const Text('Sign in'), - ), - ), - ], - ), - ), - ), - ), - ); -} diff --git a/lib/13/go/books/src/widgets/author_list.dart b/lib/13/go/books/src/widgets/author_list.dart deleted file mode 100644 index 371e30a..0000000 --- a/lib/13/go/books/src/widgets/author_list.dart +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; - -import '../data.dart'; - -/// The author list view. -class AuthorList extends StatelessWidget { - /// Creates an [AuthorList]. - const AuthorList({ - required this.authors, - this.onTap, - super.key, - }); - - /// The list of authors to be shown. - final List authors; - - /// Called when the user taps an author. - final ValueChanged? onTap; - - @override - Widget build(BuildContext context) => ListView.builder( - itemCount: authors.length, - itemBuilder: (BuildContext context, int index) => ListTile( - title: Text( - authors[index].name, - ), - subtitle: Text( - '${authors[index].books.length} books', - ), - onTap: onTap != null ? () => onTap!(authors[index]) : null, - ), - ); -} diff --git a/lib/13/go/books/src/widgets/book_list.dart b/lib/13/go/books/src/widgets/book_list.dart deleted file mode 100644 index 3e2761f..0000000 --- a/lib/13/go/books/src/widgets/book_list.dart +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; - -import '../data.dart'; - -/// The book list view. -class BookList extends StatelessWidget { - /// Creates an [BookList]. - const BookList({ - required this.books, - this.onTap, - super.key, - }); - - /// The list of books to be displayed. - final List books; - - /// Called when the user taps a book. - final ValueChanged? onTap; - - @override - Widget build(BuildContext context) => ListView.builder( - itemCount: books.length, - itemBuilder: (BuildContext context, int index) => ListTile( - title: Text( - books[index].title, - ), - subtitle: Text( - books[index].author.name, - ), - onTap: onTap != null ? () => onTap!(books[index]) : null, - ), - ); -} diff --git a/lib/13/go/exception_handling.dart b/lib/13/go/exception_handling.dart deleted file mode 100644 index 82c10e3..0000000 --- a/lib/13/go/exception_handling.dart +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -/// This sample app shows how to use `GoRouter.onException` to redirect on -/// exception. -/// -/// The first route '/' is mapped to [HomeScreen], and the second route -/// '/404' is mapped to [NotFoundScreen]. -/// -/// Any other unknown route or exception is redirected to `/404`. -void main() => runApp(const MyApp()); - -/// The route configuration. -final GoRouter _router = GoRouter( - onException: (_, GoRouterState state, GoRouter router) { - router.go('/404', extra: state.uri.toString()); - }, - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) { - return const HomeScreen(); - }, - ), - GoRoute( - path: '/404', - builder: (BuildContext context, GoRouterState state) { - return NotFoundScreen(uri: state.extra as String? ?? ''); - }, - ), - ], -); - -/// The main app. -class MyApp extends StatelessWidget { - /// Constructs a [MyApp] - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - routerConfig: _router, - ); - } -} - -/// The home screen -class HomeScreen extends StatelessWidget { - /// Constructs a [HomeScreen] - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Home Screen')), - body: Center( - child: ElevatedButton( - onPressed: () => context.go('/some-unknown-route'), - child: const Text('Simulates user entering unknown url'), - ), - ), - ); - } -} - -/// The not found screen -class NotFoundScreen extends StatelessWidget { - /// Constructs a [HomeScreen] - const NotFoundScreen({super.key, required this.uri}); - - /// The uri that can not be found. - final String uri; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Page Not Found')), - body: Center( - child: Text("Can't find a page for: $uri"), - ), - ); - } -} diff --git a/lib/13/go/main.dart b/lib/13/go/main.dart deleted file mode 100644 index d159648..0000000 --- a/lib/13/go/main.dart +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -/// This sample app shows an app with two screens. -/// -/// The first route '/' is mapped to [HomeScreen], and the second route -/// '/details' is mapped to [DetailsScreen]. -/// -/// The buttons use context.go() to navigate to each destination. On mobile -/// devices, each destination is deep-linkable and on the web, can be navigated -/// to using the address bar. -void main() => runApp(const MyApp()); - -/// The route configuration. -final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) { - return const HomeScreen(); - }, - routes: [ - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) { - return const DetailsScreen(); - }, - ), - ], - ), - ], -); - -/// The main app. -class MyApp extends StatelessWidget { - /// Constructs a [MyApp] - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - routerConfig: _router, - ); - } -} - -/// The home screen -class HomeScreen extends StatelessWidget { - /// Constructs a [HomeScreen] - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Home Screen')), - body: Center( - child: ElevatedButton( - onPressed: () => context.go('/details'), - child: const Text('Go to the Details screen'), - ), - ), - ); - } -} - -/// The details screen -class DetailsScreen extends StatelessWidget { - /// Constructs a [DetailsScreen] - const DetailsScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Details Screen')), - body: Center( - child: ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go back to the Home screen'), - ), - ), - ); - } -} diff --git a/lib/13/go/named_routes.dart b/lib/13/go/named_routes.dart deleted file mode 100644 index 9685fc4..0000000 --- a/lib/13/go/named_routes.dart +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -// This scenario demonstrates how to navigate using named locations instead of -// URLs. -// -// Instead of hardcoding the URI locations , you can also use the named -// locations. To use this API, give a unique name to each GoRoute. The name can -// then be used in context.namedLocation to be translate back to the actual URL -// location. - -/// Family data class. -class Family { - /// Create a family. - const Family({required this.name, required this.people}); - - /// The last name of the family. - final String name; - - /// The people in the family. - final Map people; -} - -/// Person data class. -class Person { - /// Creates a person. - const Person({required this.name, required this.age}); - - /// The first name of the person. - final String name; - - /// The age of the person. - final int age; -} - -const Map _families = { - 'f1': Family( - name: 'Doe', - people: { - 'p1': Person(name: 'Jane', age: 23), - 'p2': Person(name: 'John', age: 6), - }, - ), - 'f2': Family( - name: 'Wong', - people: { - 'p1': Person(name: 'June', age: 51), - 'p2': Person(name: 'Xin', age: 44), - }, - ), -}; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Named Routes'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - debugShowCheckedModeBanner: false, - ); - - late final GoRouter _router = GoRouter( - debugLogDiagnostics: true, - routes: [ - GoRoute( - name: 'home', - path: '/', - builder: (BuildContext context, GoRouterState state) => - const HomeScreen(), - routes: [ - GoRoute( - name: 'family', - path: 'family/:fid', - builder: (BuildContext context, GoRouterState state) => - FamilyScreen(fid: state.pathParameters['fid']!), - routes: [ - GoRoute( - name: 'person', - path: 'person/:pid', - builder: (BuildContext context, GoRouterState state) { - return PersonScreen( - fid: state.pathParameters['fid']!, - pid: state.pathParameters['pid']!); - }, - ), - ], - ), - ], - ), - ], - ); -} - -/// The home screen that shows a list of families. -class HomeScreen extends StatelessWidget { - /// Creates a [HomeScreen]. - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text(App.title), - ), - body: ListView( - children: [ - for (final MapEntry entry in _families.entries) - ListTile( - title: Text(entry.value.name), - onTap: () => context.go(context.namedLocation('family', - pathParameters: {'fid': entry.key})), - ) - ], - ), - ); - } -} - -/// The screen that shows a list of persons in a family. -class FamilyScreen extends StatelessWidget { - /// Creates a [FamilyScreen]. - const FamilyScreen({required this.fid, super.key}); - - /// The id family to display. - final String fid; - - @override - Widget build(BuildContext context) { - final Map people = _families[fid]!.people; - return Scaffold( - appBar: AppBar(title: Text(_families[fid]!.name)), - body: ListView( - children: [ - for (final MapEntry entry in people.entries) - ListTile( - title: Text(entry.value.name), - onTap: () => context.go(context.namedLocation( - 'person', - pathParameters: {'fid': fid, 'pid': entry.key}, - queryParameters: {'qid': 'quid'}, - )), - ), - ], - ), - ); - } -} - -/// The person screen. -class PersonScreen extends StatelessWidget { - /// Creates a [PersonScreen]. - const PersonScreen({required this.fid, required this.pid, super.key}); - - /// The id of family this person belong to. - final String fid; - - /// The id of the person to be displayed. - final String pid; - - @override - Widget build(BuildContext context) { - final Family family = _families[fid]!; - final Person person = family.people[pid]!; - return Scaffold( - appBar: AppBar(title: Text(person.name)), - body: Text('${person.name} ${family.name} is ${person.age} years old'), - ); - } -} diff --git a/lib/13/go/others/custom_stateful_shell_route.dart b/lib/13/go/others/custom_stateful_shell_route.dart deleted file mode 100644 index 5fbe2b6..0000000 --- a/lib/13/go/others/custom_stateful_shell_route.dart +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -final GlobalKey _rootNavigatorKey = - GlobalKey(debugLabel: 'root'); -final GlobalKey _tabANavigatorKey = - GlobalKey(debugLabel: 'tabANav'); - -// This example demonstrates how to setup nested navigation using a -// BottomNavigationBar, where each bar item uses its own persistent navigator, -// i.e. navigation state is maintained separately for each item. This setup also -// enables deep linking into nested pages. -// -// This example also demonstrates how build a nested shell with a custom -// container for the branch Navigators (in this case a TabBarView). - -void main() { - runApp(NestedTabNavigationExampleApp()); -} - -/// An example demonstrating how to use nested navigators -class NestedTabNavigationExampleApp extends StatelessWidget { - /// Creates a NestedTabNavigationExampleApp - NestedTabNavigationExampleApp({super.key}); - - final GoRouter _router = GoRouter( - navigatorKey: _rootNavigatorKey, - initialLocation: '/a', - routes: [ - StatefulShellRoute( - builder: (BuildContext context, GoRouterState state, - StatefulNavigationShell navigationShell) { - // This nested StatefulShellRoute demonstrates the use of a - // custom container for the branch Navigators. In this implementation, - // no customization is done in the builder function (navigationShell - // itself is simply used as the Widget for the route). Instead, the - // navigatorContainerBuilder function below is provided to - // customize the container for the branch Navigators. - return navigationShell; - }, - navigatorContainerBuilder: (BuildContext context, - StatefulNavigationShell navigationShell, List children) { - // Returning a customized container for the branch - // Navigators (i.e. the `List children` argument). - // - // See ScaffoldWithNavBar for more details on how the children - // are managed (using AnimatedBranchContainer). - return ScaffoldWithNavBar( - navigationShell: navigationShell, children: children); - }, - branches: [ - // The route branch for the first tab of the bottom navigation bar. - StatefulShellBranch( - navigatorKey: _tabANavigatorKey, - routes: [ - GoRoute( - // The screen to display as the root in the first tab of the - // bottom navigation bar. - path: '/a', - builder: (BuildContext context, GoRouterState state) => - const RootScreenA(), - routes: [ - // The details screen to display stacked on navigator of the - // first tab. This will cover screen A but not the application - // shell (bottom navigation bar). - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) => - const DetailsScreen(label: 'A'), - ), - ], - ), - ], - ), - - // The route branch for the third tab of the bottom navigation bar. - StatefulShellBranch( - // StatefulShellBranch will automatically use the first descendant - // GoRoute as the initial location of the branch. If another route - // is desired, specify the location of it using the defaultLocation - // parameter. - // defaultLocation: '/c2', - routes: [ - StatefulShellRoute( - builder: (BuildContext context, GoRouterState state, - StatefulNavigationShell navigationShell) { - // Just like with the top level StatefulShellRoute, no - // customization is done in the builder function. - return navigationShell; - }, - navigatorContainerBuilder: (BuildContext context, - StatefulNavigationShell navigationShell, - List children) { - // Returning a customized container for the branch - // Navigators (i.e. the `List children` argument). - // - // See TabbedRootScreen for more details on how the children - // are managed (in a TabBarView). - return TabbedRootScreen( - navigationShell: navigationShell, children: children); - }, - // This bottom tab uses a nested shell, wrapping sub routes in a - // top TabBar. - branches: [ - StatefulShellBranch(routes: [ - GoRoute( - path: '/b1', - builder: (BuildContext context, GoRouterState state) => - const TabScreen( - label: 'B1', detailsPath: '/b1/details'), - routes: [ - GoRoute( - path: 'details', - builder: - (BuildContext context, GoRouterState state) => - const DetailsScreen( - label: 'B1', - withScaffold: false, - ), - ), - ], - ), - ]), - StatefulShellBranch(routes: [ - GoRoute( - path: '/b2', - builder: (BuildContext context, GoRouterState state) => - const TabScreen( - label: 'B2', detailsPath: '/b2/details'), - routes: [ - GoRoute( - path: 'details', - builder: - (BuildContext context, GoRouterState state) => - const DetailsScreen( - label: 'B2', - withScaffold: false, - ), - ), - ], - ), - ]), - ], - ), - ], - ), - ], - ), - ], - ); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - routerConfig: _router, - ); - } -} - -/// Builds the "shell" for the app by building a Scaffold with a -/// BottomNavigationBar, where [child] is placed in the body of the Scaffold. -class ScaffoldWithNavBar extends StatelessWidget { - /// Constructs an [ScaffoldWithNavBar]. - const ScaffoldWithNavBar({ - required this.navigationShell, - required this.children, - Key? key, - }) : super(key: key ?? const ValueKey('ScaffoldWithNavBar')); - - /// The navigation shell and container for the branch Navigators. - final StatefulNavigationShell navigationShell; - - /// The children (branch Navigators) to display in a custom container - /// ([AnimatedBranchContainer]). - final List children; - - @override - Widget build(BuildContext context) { - return Scaffold( - body: AnimatedBranchContainer( - currentIndex: navigationShell.currentIndex, - children: children, - ), - bottomNavigationBar: BottomNavigationBar( - // Here, the items of BottomNavigationBar are hard coded. In a real - // world scenario, the items would most likely be generated from the - // branches of the shell route, which can be fetched using - // `navigationShell.route.branches`. - items: const [ - BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'), - BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'), - ], - currentIndex: navigationShell.currentIndex, - onTap: (int index) => _onTap(context, index), - ), - ); - } - - /// Navigate to the current location of the branch at the provided index when - /// tapping an item in the BottomNavigationBar. - void _onTap(BuildContext context, int index) { - // When navigating to a new branch, it's recommended to use the goBranch - // method, as doing so makes sure the last navigation state of the - // Navigator for the branch is restored. - navigationShell.goBranch( - index, - // A common pattern when using bottom navigation bars is to support - // navigating to the initial location when tapping the item that is - // already active. This example demonstrates how to support this behavior, - // using the initialLocation parameter of goBranch. - initialLocation: index == navigationShell.currentIndex, - ); - } -} - -/// Custom branch Navigator container that provides animated transitions -/// when switching branches. -class AnimatedBranchContainer extends StatelessWidget { - /// Creates a AnimatedBranchContainer - const AnimatedBranchContainer( - {super.key, required this.currentIndex, required this.children}); - - /// The index (in [children]) of the branch Navigator to display. - final int currentIndex; - - /// The children (branch Navigators) to display in this container. - final List children; - - @override - Widget build(BuildContext context) { - return Stack( - children: children.mapIndexed( - (int index, Widget navigator) { - return AnimatedScale( - scale: index == currentIndex ? 1 : 1.5, - duration: const Duration(milliseconds: 400), - child: AnimatedOpacity( - opacity: index == currentIndex ? 1 : 0, - duration: const Duration(milliseconds: 400), - child: _branchNavigatorWrapper(index, navigator), - ), - ); - }, - ).toList()); - } - - Widget _branchNavigatorWrapper(int index, Widget navigator) => IgnorePointer( - ignoring: index != currentIndex, - child: TickerMode( - enabled: index == currentIndex, - child: navigator, - ), - ); -} - -/// Widget for the root page for the first section of the bottom navigation bar. -class RootScreenA extends StatelessWidget { - /// Creates a RootScreenA - const RootScreenA({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Root of section A'), - ), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Screen A', style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - GoRouter.of(context).go('/a/details'); - }, - child: const Text('View details'), - ), - ], - ), - ), - ); - } -} - -/// The details screen for either the A or B screen. -class DetailsScreen extends StatefulWidget { - /// Constructs a [DetailsScreen]. - const DetailsScreen({ - required this.label, - this.param, - this.withScaffold = true, - super.key, - }); - - /// The label to display in the center of the screen. - final String label; - - /// Optional param - final String? param; - - /// Wrap in scaffold - final bool withScaffold; - - @override - State createState() => DetailsScreenState(); -} - -/// The state for DetailsScreen -class DetailsScreenState extends State { - int _counter = 0; - - @override - Widget build(BuildContext context) { - if (widget.withScaffold) { - return Scaffold( - appBar: AppBar( - title: Text('Details Screen - ${widget.label}'), - ), - body: _build(context), - ); - } else { - return Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: _build(context), - ); - } - } - - Widget _build(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Details for ${widget.label} - Counter: $_counter', - style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - setState(() { - _counter++; - }); - }, - child: const Text('Increment counter'), - ), - const Padding(padding: EdgeInsets.all(8)), - if (widget.param != null) - Text('Parameter: ${widget.param!}', - style: Theme.of(context).textTheme.titleMedium), - const Padding(padding: EdgeInsets.all(8)), - if (!widget.withScaffold) ...[ - const Padding(padding: EdgeInsets.all(16)), - TextButton( - onPressed: () { - GoRouter.of(context).pop(); - }, - child: const Text('< Back', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), - ), - ] - ], - ), - ); - } -} - -/// Builds a nested shell using a [TabBar] and [TabBarView]. -class TabbedRootScreen extends StatefulWidget { - /// Constructs a TabbedRootScreen - const TabbedRootScreen( - {required this.navigationShell, required this.children, super.key}); - - /// The current state of the parent StatefulShellRoute. - final StatefulNavigationShell navigationShell; - - /// The children (branch Navigators) to display in the [TabBarView]. - final List children; - - @override - State createState() => _TabbedRootScreenState(); -} - -class _TabbedRootScreenState extends State - with SingleTickerProviderStateMixin { - late final TabController _tabController = TabController( - length: widget.children.length, - vsync: this, - initialIndex: widget.navigationShell.currentIndex); - - @override - void didUpdateWidget(covariant TabbedRootScreen oldWidget) { - super.didUpdateWidget(oldWidget); - _tabController.index = widget.navigationShell.currentIndex; - } - - @override - Widget build(BuildContext context) { - final List tabs = widget.children - .mapIndexed((int i, _) => Tab(text: 'Tab ${i + 1}')) - .toList(); - - return Scaffold( - appBar: AppBar( - title: const Text('Root of Section B (nested TabBar shell)'), - bottom: TabBar( - controller: _tabController, - tabs: tabs, - onTap: (int tappedIndex) => _onTabTap(context, tappedIndex), - )), - body: TabBarView( - controller: _tabController, - children: widget.children, - ), - ); - } - - void _onTabTap(BuildContext context, int index) { - widget.navigationShell.goBranch(index); - } -} - -/// Widget for the pages in the top tab bar. -class TabScreen extends StatelessWidget { - /// Creates a RootScreen - const TabScreen({required this.label, required this.detailsPath, super.key}); - - /// The label - final String label; - - /// The path to the detail page - final String detailsPath; - - @override - Widget build(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Screen $label', style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - GoRouter.of(context).go(detailsPath); - }, - child: const Text('View details'), - ), - ], - ), - ); - } -} diff --git a/lib/13/go/others/error_screen.dart b/lib/13/go/others/error_screen.dart deleted file mode 100644 index 5c071fc..0000000 --- a/lib/13/go/others/error_screen.dart +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Custom Error Screen'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1Screen(), - ), - GoRoute( - path: '/page2', - builder: (BuildContext context, GoRouterState state) => - const Page2Screen(), - ), - ], - errorBuilder: (BuildContext context, GoRouterState state) => - ErrorScreen(state.error!), - ); -} - -/// The screen of the first page. -class Page1Screen extends StatelessWidget { - /// Creates a [Page1Screen]. - const Page1Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/page2'), - child: const Text('Go to page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2Screen extends StatelessWidget { - /// Creates a [Page2Screen]. - const Page2Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ], - ), - ), - ); -} - -/// The screen of the error page. -class ErrorScreen extends StatelessWidget { - /// Creates an [ErrorScreen]. - const ErrorScreen(this.error, {super.key}); - - /// The error to display. - final Exception error; - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text('My "Page Not Found" Screen')), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SelectableText(error.toString()), - TextButton( - onPressed: () => context.go('/'), - child: const Text('Home'), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/extra_param.dart b/lib/13/go/others/extra_param.dart deleted file mode 100644 index eaef755..0000000 --- a/lib/13/go/others/extra_param.dart +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -/// Family data class. -class Family { - /// Create a family. - const Family({required this.name, required this.people}); - - /// The last name of the family. - final String name; - - /// The people in the family. - final Map people; -} - -/// Person data class. -class Person { - /// Creates a person. - const Person({required this.name, required this.age}); - - /// The first name of the person. - final String name; - - /// The age of the person. - final int age; -} - -const Map _families = { - 'f1': Family( - name: 'Doe', - people: { - 'p1': Person(name: 'Jane', age: 23), - 'p2': Person(name: 'John', age: 6), - }, - ), - 'f2': Family( - name: 'Wong', - people: { - 'p1': Person(name: 'June', age: 51), - 'p2': Person(name: 'Xin', age: 44), - }, - ), -}; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Extra Parameter'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - name: 'home', - path: '/', - builder: (BuildContext context, GoRouterState state) => - const HomeScreen(), - routes: [ - GoRoute( - name: 'family', - path: 'family', - builder: (BuildContext context, GoRouterState state) { - final Map params = - state.extra! as Map; - final String fid = params['fid']! as String; - return FamilyScreen(fid: fid); - }, - ), - ], - ), - ], - ); -} - -/// The home screen that shows a list of families. -class HomeScreen extends StatelessWidget { - /// Creates a [HomeScreen]. - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: ListView( - children: [ - for (final MapEntry entry in _families.entries) - ListTile( - title: Text(entry.value.name), - onTap: () => context.goNamed('family', - extra: {'fid': entry.key}), - ) - ], - ), - ); -} - -/// The screen that shows a list of persons in a family. -class FamilyScreen extends StatelessWidget { - /// Creates a [FamilyScreen]. - const FamilyScreen({required this.fid, super.key}); - - /// The family to display. - final String fid; - - @override - Widget build(BuildContext context) { - final Map people = _families[fid]!.people; - return Scaffold( - appBar: AppBar(title: Text(_families[fid]!.name)), - body: ListView( - children: [ - for (final Person p in people.values) - ListTile( - title: Text(p.name), - ), - ], - ), - ); - } -} diff --git a/lib/13/go/others/init_loc.dart b/lib/13/go/others/init_loc.dart deleted file mode 100644 index 4f61b00..0000000 --- a/lib/13/go/others/init_loc.dart +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Initial Location'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - final GoRouter _router = GoRouter( - initialLocation: '/page3', - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1Screen(), - ), - GoRoute( - path: '/page2', - builder: (BuildContext context, GoRouterState state) => - const Page2Screen(), - ), - GoRoute( - path: '/page3', - builder: (BuildContext context, GoRouterState state) => - const Page3Screen(), - ), - ], - ); -} - -/// The screen of the first page. -class Page1Screen extends StatelessWidget { - /// Creates a [Page1Screen]. - const Page1Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/page2'), - child: const Text('Go to page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2Screen extends StatelessWidget { - /// Creates a [Page2Screen]. - const Page2Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ], - ), - ), - ); -} - -/// The screen of the third page. -class Page3Screen extends StatelessWidget { - /// Creates a [Page3Screen]. - const Page3Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/page2'), - child: const Text('Go to page 2'), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/nav_observer.dart b/lib/13/go/others/nav_observer.dart deleted file mode 100644 index 038d337..0000000 --- a/lib/13/go/others/nav_observer.dart +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; -import 'package:logging/logging.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Navigator Observer'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - final GoRouter _router = GoRouter( - observers: [MyNavObserver()], - routes: [ - GoRoute( - // if there's no name, path will be used as name for observers - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1Screen(), - routes: [ - GoRoute( - name: 'page2', - path: 'page2/:p1', - builder: (BuildContext context, GoRouterState state) => - const Page2Screen(), - routes: [ - GoRoute( - name: 'page3', - path: 'page3', - builder: (BuildContext context, GoRouterState state) => - const Page3Screen(), - ), - ], - ), - ], - ), - ], - ); -} - -/// The Navigator observer. -class MyNavObserver extends NavigatorObserver { - /// Creates a [MyNavObserver]. - MyNavObserver() { - log.onRecord.listen((LogRecord e) => debugPrint('$e')); - } - - /// The logged message. - final Logger log = Logger('MyNavObserver'); - - @override - void didPush(Route route, Route? previousRoute) => - log.info('didPush: ${route.str}, previousRoute= ${previousRoute?.str}'); - - @override - void didPop(Route route, Route? previousRoute) => - log.info('didPop: ${route.str}, previousRoute= ${previousRoute?.str}'); - - @override - void didRemove(Route route, Route? previousRoute) => - log.info('didRemove: ${route.str}, previousRoute= ${previousRoute?.str}'); - - @override - void didReplace({Route? newRoute, Route? oldRoute}) => - log.info('didReplace: new= ${newRoute?.str}, old= ${oldRoute?.str}'); - - @override - void didStartUserGesture( - Route route, - Route? previousRoute, - ) => - log.info('didStartUserGesture: ${route.str}, ' - 'previousRoute= ${previousRoute?.str}'); - - @override - void didStopUserGesture() => log.info('didStopUserGesture'); -} - -extension on Route { - String get str => 'route(${settings.name}: ${settings.arguments})'; -} - -/// The screen of the first page. -class Page1Screen extends StatelessWidget { - /// Creates a [Page1Screen]. - const Page1Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.goNamed( - 'page2', - pathParameters: {'p1': 'pv1'}, - queryParameters: {'q1': 'qv1'}, - ), - child: const Text('Go to page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2Screen extends StatelessWidget { - /// Creates a [Page2Screen]. - const Page2Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.goNamed( - 'page3', - pathParameters: {'p1': 'pv2'}, - ), - child: const Text('Go to page 3'), - ), - ], - ), - ), - ); -} - -/// The screen of the third page. -class Page3Screen extends StatelessWidget { - /// Creates a [Page3Screen]. - const Page3Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/push.dart b/lib/13/go/others/push.dart deleted file mode 100644 index 0cea894..0000000 --- a/lib/13/go/others/push.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Push'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1ScreenWithPush(), - ), - GoRoute( - path: '/page2', - builder: (BuildContext context, GoRouterState state) => - Page2ScreenWithPush( - int.parse(state.uri.queryParameters['push-count']!), - ), - ), - ], - ); -} - -/// The screen of the first page. -class Page1ScreenWithPush extends StatelessWidget { - /// Creates a [Page1ScreenWithPush]. - const Page1ScreenWithPush({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text('${App.title}: page 1')), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.push('/page2?push-count=1'), - child: const Text('Push page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2ScreenWithPush extends StatelessWidget { - /// Creates a [Page2ScreenWithPush]. - const Page2ScreenWithPush(this.pushCount, {super.key}); - - /// The push count. - final int pushCount; - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: Text('${App.title}: page 2 w/ push count $pushCount'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ), - Padding( - padding: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () => context.push( - '/page2?push-count=${pushCount + 1}', - ), - child: const Text('Push page 2 (again)'), - ), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/router_neglect.dart b/lib/13/go/others/router_neglect.dart deleted file mode 100644 index 75686a1..0000000 --- a/lib/13/go/others/router_neglect.dart +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Router neglect'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - final GoRouter _router = GoRouter( - // turn off history tracking in the browser for this navigation - routerNeglect: true, - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1Screen(), - ), - GoRoute( - path: '/page2', - builder: (BuildContext context, GoRouterState state) => - const Page2Screen(), - ), - ], - ); -} - -/// The screen of the first page. -class Page1Screen extends StatelessWidget { - /// Creates a [Page1Screen]. - const Page1Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/page2'), - child: const Text('Go to page 2'), - ), - const SizedBox(height: 8), - ElevatedButton( - // turn off history tracking in the browser for this navigation; - // note that this isn't necessary when you've set routerNeglect - // but it does illustrate the technique - onPressed: () => Router.neglect( - context, - () => context.push('/page2'), - ), - child: const Text('Push page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2Screen extends StatelessWidget { - /// Creates a [Page2Screen]. - const Page2Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/state_restoration.dart b/lib/13/go/others/state_restoration.dart deleted file mode 100644 index 93e8aca..0000000 --- a/lib/13/go/others/state_restoration.dart +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp( - const RootRestorationScope(restorationId: 'root', child: App()), - ); - -/// The main app. -class App extends StatefulWidget { - /// Creates an [App]. - const App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: State Restoration'; - - @override - State createState() => _AppState(); -} - -class _AppState extends State with RestorationMixin { - @override - String get restorationId => 'wrapper'; - - @override - void restoreState(RestorationBucket? oldBucket, bool initialRestore) { - // Implement restoreState for your app - } - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: App.title, - restorationScopeId: 'app', - ); - - final GoRouter _router = GoRouter( - routes: [ - // restorationId set for the route automatically - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const Page1Screen(), - ), - - // restorationId set for the route automatically - GoRoute( - path: '/page2', - builder: (BuildContext context, GoRouterState state) => - const Page2Screen(), - ), - ], - restorationScopeId: 'router', - ); -} - -/// The screen of the first page. -class Page1Screen extends StatelessWidget { - /// Creates a [Page1Screen]. - const Page1Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/page2'), - child: const Text('Go to page 2'), - ), - ], - ), - ), - ); -} - -/// The screen of the second page. -class Page2Screen extends StatelessWidget { - /// Creates a [Page2Screen]. - const Page2Screen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go to home page'), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/others/stateful_shell_state_restoration.dart b/lib/13/go/others/stateful_shell_state_restoration.dart deleted file mode 100644 index aeecd11..0000000 --- a/lib/13/go/others/stateful_shell_state_restoration.dart +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(RestorableStatefulShellRouteExampleApp()); - -/// An example demonstrating how to use StatefulShellRoute with state -/// restoration. -class RestorableStatefulShellRouteExampleApp extends StatelessWidget { - /// Creates a NestedTabNavigationExampleApp - RestorableStatefulShellRouteExampleApp({super.key}); - - final GoRouter _router = GoRouter( - initialLocation: '/a', - restorationScopeId: 'router', - routes: [ - StatefulShellRoute.indexedStack( - restorationScopeId: 'shell1', - pageBuilder: (BuildContext context, GoRouterState state, - StatefulNavigationShell navigationShell) { - return MaterialPage( - restorationId: 'shellWidget1', - child: ScaffoldWithNavBar(navigationShell: navigationShell)); - }, - branches: [ - // The route branch for the first tab of the bottom navigation bar. - StatefulShellBranch( - restorationScopeId: 'branchA', - routes: [ - GoRoute( - // The screen to display as the root in the first tab of the - // bottom navigation bar. - path: '/a', - pageBuilder: (BuildContext context, GoRouterState state) => - const MaterialPage( - restorationId: 'screenA', - child: - RootScreen(label: 'A', detailsPath: '/a/details')), - routes: [ - // The details screen to display stacked on navigator of the - // first tab. This will cover screen A but not the application - // shell (bottom navigation bar). - GoRoute( - path: 'details', - pageBuilder: (BuildContext context, GoRouterState state) => - const MaterialPage( - restorationId: 'screenADetail', - child: DetailsScreen(label: 'A')), - ), - ], - ), - ], - ), - // The route branch for the second tab of the bottom navigation bar. - StatefulShellBranch( - restorationScopeId: 'branchB', - routes: [ - GoRoute( - // The screen to display as the root in the second tab of the - // bottom navigation bar. - path: '/b', - pageBuilder: (BuildContext context, GoRouterState state) => - const MaterialPage( - restorationId: 'screenB', - child: - RootScreen(label: 'B', detailsPath: '/b/details')), - routes: [ - // The details screen to display stacked on navigator of the - // first tab. This will cover screen A but not the application - // shell (bottom navigation bar). - GoRoute( - path: 'details', - pageBuilder: (BuildContext context, GoRouterState state) => - const MaterialPage( - restorationId: 'screenBDetail', - child: DetailsScreen(label: 'B')), - ), - ], - ), - ], - ), - ], - ), - ], - ); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - restorationScopeId: 'app', - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - routerConfig: _router, - ); - } -} - -/// Builds the "shell" for the app by building a Scaffold with a -/// BottomNavigationBar, where [child] is placed in the body of the Scaffold. -class ScaffoldWithNavBar extends StatelessWidget { - /// Constructs an [ScaffoldWithNavBar]. - const ScaffoldWithNavBar({ - required this.navigationShell, - Key? key, - }) : super(key: key ?? const ValueKey('ScaffoldWithNavBar')); - - /// The navigation shell and container for the branch Navigators. - final StatefulNavigationShell navigationShell; - - @override - Widget build(BuildContext context) { - return Scaffold( - body: navigationShell, - bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'), - BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'), - ], - currentIndex: navigationShell.currentIndex, - onTap: (int tappedIndex) => navigationShell.goBranch(tappedIndex), - ), - ); - } -} - -/// Widget for the root/initial pages in the bottom navigation bar. -class RootScreen extends StatelessWidget { - /// Creates a RootScreen - const RootScreen({ - required this.label, - required this.detailsPath, - super.key, - }); - - /// The label - final String label; - - /// The path to the detail page - final String detailsPath; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('Root of section $label'), - ), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Screen $label', - style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - GoRouter.of(context).go(detailsPath); - }, - child: const Text('View details'), - ), - ], - ), - ), - ); - } -} - -/// The details screen for either the A or B screen. -class DetailsScreen extends StatefulWidget { - /// Constructs a [DetailsScreen]. - const DetailsScreen({ - required this.label, - super.key, - }); - - /// The label to display in the center of the screen. - final String label; - - @override - State createState() => DetailsScreenState(); -} - -/// The state for DetailsScreen -class DetailsScreenState extends State with RestorationMixin { - final RestorableInt _counter = RestorableInt(0); - - @override - String? get restorationId => 'DetailsScreen-${widget.label}'; - - @override - void restoreState(RestorationBucket? oldBucket, bool initialRestore) { - registerForRestoration(_counter, 'counter'); - } - - @override - void dispose() { - super.dispose(); - _counter.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('Details Screen - ${widget.label}'), - ), - body: _build(context), - ); - } - - Widget _build(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Details for ${widget.label} - Counter: ${_counter.value}', - style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - setState(() { - _counter.value++; - }); - }, - child: const Text('Increment counter'), - ), - const Padding(padding: EdgeInsets.all(8)), - ], - ), - ); - } -} diff --git a/lib/13/go/others/transitions.dart b/lib/13/go/others/transitions.dart deleted file mode 100644 index e4b9a3e..0000000 --- a/lib/13/go/others/transitions.dart +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Custom Transitions'; - - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - ); - - final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - redirect: (_, __) => '/none', - ), - GoRoute( - path: '/fade', - pageBuilder: (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'fade', - color: Colors.red, - ), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) => - FadeTransition(opacity: animation, child: child), - ), - ), - GoRoute( - path: '/scale', - pageBuilder: (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'scale', - color: Colors.green, - ), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) => - ScaleTransition(scale: animation, child: child), - ), - ), - GoRoute( - path: '/slide', - pageBuilder: (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'slide', - color: Colors.yellow, - ), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) => - SlideTransition( - position: animation.drive( - Tween( - begin: const Offset(0.25, 0.25), - end: Offset.zero, - ).chain(CurveTween(curve: Curves.easeIn)), - ), - child: child, - ), - ), - ), - GoRoute( - path: '/rotation', - pageBuilder: (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'rotation', - color: Colors.purple, - ), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) => - RotationTransition(turns: animation, child: child), - ), - ), - GoRoute( - path: '/none', - pageBuilder: (BuildContext context, GoRouterState state) => - NoTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'none', - color: Colors.white, - ), - ), - ), - ], - ); -} - -/// An Example transitions screen. -class ExampleTransitionsScreen extends StatelessWidget { - /// Creates an [ExampleTransitionsScreen]. - const ExampleTransitionsScreen({ - required this.color, - required this.kind, - super.key, - }); - - /// The available transition kinds. - static final List kinds = [ - 'fade', - 'scale', - 'slide', - 'rotation', - 'none' - ]; - - /// The color of the container. - final Color color; - - /// The transition kind. - final String kind; - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: Text('${App.title}: $kind')), - body: Container( - color: color, - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - for (final String kind in kinds) - Padding( - padding: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () => context.go('/$kind'), - child: Text('$kind transition'), - ), - ) - ], - ), - ), - ), - ); -} diff --git a/lib/13/go/path_and_query_parameters.dart b/lib/13/go/path_and_query_parameters.dart deleted file mode 100644 index 3a8f289..0000000 --- a/lib/13/go/path_and_query_parameters.dart +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -// This scenario demonstrates how to use path parameters and query parameters. -// -// The route segments that start with ':' are treated as path parameters when -// defining GoRoute[s]. The parameter values can be accessed through -// GoRouterState.pathParameters. -// -// The query parameters are automatically stored in GoRouterState.queryParameters. - -/// Family data class. -class Family { - /// Create a family. - const Family({required this.name, required this.people}); - - /// The last name of the family. - final String name; - - /// The people in the family. - final Map people; -} - -/// Person data class. -class Person { - /// Creates a person. - const Person({required this.name, required this.age}); - - /// The first name of the person. - final String name; - - /// The age of the person. - final int age; -} - -const Map _families = { - 'f1': Family( - name: 'Doe', - people: { - 'p1': Person(name: 'Jane', age: 23), - 'p2': Person(name: 'John', age: 6), - }, - ), - 'f2': Family( - name: 'Wong', - people: { - 'p1': Person(name: 'June', age: 51), - 'p2': Person(name: 'Xin', age: 44), - }, - ), -}; - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - /// The title of the app. - static const String title = 'GoRouter Example: Query Parameters'; - - // add the login info into the tree as app state that can change over time - @override - Widget build(BuildContext context) => MaterialApp.router( - routerConfig: _router, - title: title, - debugShowCheckedModeBanner: false, - ); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const HomeScreen(), - routes: [ - GoRoute( - name: 'family', - path: 'family/:fid', - builder: (BuildContext context, GoRouterState state) { - return FamilyScreen( - fid: state.pathParameters['fid']!, - asc: state.uri.queryParameters['sort'] == 'asc', - ); - }), - ], - ), - ], - ); -} - -/// The home screen that shows a list of families. -class HomeScreen extends StatelessWidget { - /// Creates a [HomeScreen]. - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text(App.title), - ), - body: ListView( - children: [ - for (final MapEntry entry in _families.entries) - ListTile( - title: Text(entry.value.name), - onTap: () => context.go('/family/${entry.key}'), - ) - ], - ), - ); - } -} - -/// The screen that shows a list of persons in a family. -class FamilyScreen extends StatelessWidget { - /// Creates a [FamilyScreen]. - const FamilyScreen({required this.fid, required this.asc, super.key}); - - /// The family to display. - final String fid; - - /// Whether to sort the name in ascending order. - final bool asc; - - @override - Widget build(BuildContext context) { - final Map newQueries; - final List names = _families[fid]! - .people - .values - .map((Person p) => p.name) - .toList(); - names.sort(); - if (asc) { - newQueries = const {'sort': 'desc'}; - } else { - newQueries = const {'sort': 'asc'}; - } - return Scaffold( - appBar: AppBar( - title: Text(_families[fid]!.name), - actions: [ - IconButton( - onPressed: () => context.goNamed('family', - pathParameters: {'fid': fid}, - queryParameters: newQueries), - tooltip: 'sort ascending or descending', - icon: const Icon(Icons.sort), - ) - ], - ), - body: ListView( - children: [ - for (final String name in asc ? names : names.reversed) - ListTile( - title: Text(name), - ), - ], - ), - ); - } -} diff --git a/lib/13/go/raw_book/main.dart b/lib/13/go/raw_book/main.dart deleted file mode 100644 index 7c97b30..0000000 --- a/lib/13/go/raw_book/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -// 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 'dart:io' show Platform; - -import 'package:flutter/foundation.dart' show kIsWeb; -import 'package:flutter/material.dart'; -import 'package:url_strategy/url_strategy.dart'; -// import 'package:window_size/window_size.dart'; - -import 'src/app.dart'; - -void main() { - // Use package:url_strategy until this pull request is released: - // https://github.com/flutter/flutter/pull/77103 - - // Use to setHashUrlStrategy() to use "/#/" in the address bar (default). Use - // setPathUrlStrategy() to use the path. You may need to configure your web - // server to redirect all paths to index.html. - // - // On mobile platforms, both functions are no-ops. - setHashUrlStrategy(); - // setPathUrlStrategy(); - runApp(const Bookstore()); -} - diff --git a/lib/13/go/raw_book/src/app.dart b/lib/13/go/raw_book/src/app.dart deleted file mode 100644 index 8cb7ba8..0000000 --- a/lib/13/go/raw_book/src/app.dart +++ /dev/null @@ -1,81 +0,0 @@ -// 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'; - -import 'auth.dart'; -import 'routing.dart'; -import 'screens/navigator.dart'; - -class Bookstore extends StatefulWidget { - const Bookstore({super.key}); - - @override - State createState() => _BookstoreState(); -} - -class _BookstoreState extends State { - late final RouteState _routeState; - late final SimpleRouterDelegate _routerDelegate; - late final TemplateRouteParser _routeParser; - - @override - void initState() { - /// Configure the parser with all of the app's allowed path templates. - _routeParser = TemplateRouteParser( - allowedPaths: [ - '/signin', - '/authors', - '/settings', - '/books/new', - '/books/all', - '/books/popular', - '/book/:bookId', - '/author/:authorId', - ], - initialRoute: '/signin', - ); - - _routeState = RouteState(_routeParser); - - _routerDelegate = SimpleRouterDelegate( - routeState: _routeState, - ); - - - super.initState(); - } - - @override - Widget build(BuildContext context) => RouteStateScope( - notifier: _routeState, - child: MaterialApp.router( - routerDelegate: _routerDelegate, - routeInformationParser: _routeParser, - // Revert back to pre-Flutter-2.5 transition behavior: - // https://github.com/flutter/flutter/issues/82053 - theme: ThemeData( - useMaterial3: true, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.linux: FadeUpwardsPageTransitionsBuilder(), - TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.windows: FadeUpwardsPageTransitionsBuilder(), - }, - ), - ), - - ), - ); - - - @override - void dispose() { - _routeState.dispose(); - _routerDelegate.dispose(); - super.dispose(); - } -} diff --git a/lib/13/go/raw_book/src/auth.dart b/lib/13/go/raw_book/src/auth.dart deleted file mode 100644 index 1e9157f..0000000 --- a/lib/13/go/raw_book/src/auth.dart +++ /dev/null @@ -1,47 +0,0 @@ -// // 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'; -// -// /// A mock authentication service -// class BookstoreAuth extends ChangeNotifier { -// bool _signedIn = false; -// -// bool get signedIn => _signedIn; -// -// Future signOut() async { -// await Future.delayed(const Duration(milliseconds: 200)); -// // Sign out. -// _signedIn = false; -// notifyListeners(); -// } -// -// Future signIn(String username, String password) async { -// await Future.delayed(const Duration(milliseconds: 200)); -// -// // Sign in. Allow any password. -// _signedIn = true; -// notifyListeners(); -// return _signedIn; -// } -// -// @override -// bool operator ==(Object other) => -// other is BookstoreAuth && other._signedIn == _signedIn; -// -// @override -// int get hashCode => _signedIn.hashCode; -// } -// -// class BookstoreAuthScope extends InheritedNotifier { -// const BookstoreAuthScope({ -// required super.notifier, -// required super.child, -// super.key, -// }); -// -// static BookstoreAuth of(BuildContext context) => context -// .dependOnInheritedWidgetOfExactType()! -// .notifier!; -// } diff --git a/lib/13/go/raw_book/src/data.dart b/lib/13/go/raw_book/src/data.dart deleted file mode 100644 index f82a31d..0000000 --- a/lib/13/go/raw_book/src/data.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -export 'data/author.dart'; -export 'data/book.dart'; -export 'data/library.dart'; diff --git a/lib/13/go/raw_book/src/data/author.dart b/lib/13/go/raw_book/src/data/author.dart deleted file mode 100644 index affd9a2..0000000 --- a/lib/13/go/raw_book/src/data/author.dart +++ /dev/null @@ -1,13 +0,0 @@ -// 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 'book.dart'; - -class Author { - final int id; - final String name; - final books = []; - - Author(this.id, this.name); -} diff --git a/lib/13/go/raw_book/src/data/book.dart b/lib/13/go/raw_book/src/data/book.dart deleted file mode 100644 index f91f038..0000000 --- a/lib/13/go/raw_book/src/data/book.dart +++ /dev/null @@ -1,15 +0,0 @@ -// 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 'author.dart'; - -class Book { - final int id; - final String title; - final Author author; - final bool isPopular; - final bool isNew; - - Book(this.id, this.title, this.isPopular, this.isNew, this.author); -} diff --git a/lib/13/go/raw_book/src/data/library.dart b/lib/13/go/raw_book/src/data/library.dart deleted file mode 100644 index 14fd496..0000000 --- a/lib/13/go/raw_book/src/data/library.dart +++ /dev/null @@ -1,61 +0,0 @@ -// 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 'author.dart'; -import 'book.dart'; - -final libraryInstance = Library() - ..addBook( - title: 'Left Hand of Darkness', - authorName: 'Ursula K. Le Guin', - isPopular: true, - isNew: true) - ..addBook( - title: 'Too Like the Lightning', - authorName: 'Ada Palmer', - isPopular: false, - isNew: true) - ..addBook( - title: 'Kindred', - authorName: 'Octavia E. Butler', - isPopular: true, - isNew: false) - ..addBook( - title: 'The Lathe of Heaven', - authorName: 'Ursula K. Le Guin', - isPopular: false, - isNew: false); - -class Library { - final List allBooks = []; - final List allAuthors = []; - - void addBook({ - required String title, - required String authorName, - required bool isPopular, - required bool isNew, - }) { - var author = allAuthors.firstWhere( - (author) => author.name == authorName, - orElse: () { - final value = Author(allAuthors.length, authorName); - allAuthors.add(value); - return value; - }, - ); - var book = Book(allBooks.length, title, isPopular, isNew, author); - - author.books.add(book); - allBooks.add(book); - } - - List get popularBooks => [ - ...allBooks.where((book) => book.isPopular), - ]; - - List get newBooks => [ - ...allBooks.where((book) => book.isNew), - ]; -} diff --git a/lib/13/go/raw_book/src/routing.dart b/lib/13/go/raw_book/src/routing.dart deleted file mode 100644 index cf0be2c..0000000 --- a/lib/13/go/raw_book/src/routing.dart +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -export 'routing/delegate.dart'; -export 'routing/parsed_route.dart'; -export 'routing/parser.dart'; -export 'routing/route_state.dart'; diff --git a/lib/13/go/raw_book/src/routing/delegate.dart b/lib/13/go/raw_book/src/routing/delegate.dart deleted file mode 100644 index 533e659..0000000 --- a/lib/13/go/raw_book/src/routing/delegate.dart +++ /dev/null @@ -1,47 +0,0 @@ -// 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 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/widgets.dart'; - -import '../screens/navigator.dart'; -import 'parsed_route.dart'; -import 'route_state.dart'; - -class SimpleRouterDelegate extends RouterDelegate - with ChangeNotifier, PopNavigatorRouterDelegateMixin { - final RouteState routeState; - - @override - final GlobalKey navigatorKey = GlobalKey(); - - SimpleRouterDelegate({ - required this.routeState, - }) { - routeState.addListener(notifyListeners); - } - - @override - Widget build(BuildContext context) => BookstoreNavigator( - navigatorKey: navigatorKey, - ); - - @override - Future setNewRoutePath(ParsedRoute configuration) async { - routeState.route = configuration; - return SynchronousFuture(null); - } - - @override - ParsedRoute get currentConfiguration => routeState.route; - - @override - void dispose() { - routeState.removeListener(notifyListeners); - routeState.dispose(); - super.dispose(); - } -} diff --git a/lib/13/go/raw_book/src/routing/parsed_route.dart b/lib/13/go/raw_book/src/routing/parsed_route.dart deleted file mode 100644 index 9a40ac7..0000000 --- a/lib/13/go/raw_book/src/routing/parsed_route.dart +++ /dev/null @@ -1,51 +0,0 @@ -// 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:quiver/core.dart'; - -import 'parser.dart'; - -/// A route path that has been parsed by [TemplateRouteParser]. -class ParsedRoute { - /// The current path location without query parameters. (/book/123) - final String path; - - /// The path template (/book/:id) - final String pathTemplate; - - /// The path parameters ({id: 123}) - final Map parameters; - - /// The query parameters ({search: abc}) - final Map queryParameters; - - static const _mapEquality = MapEquality(); - - ParsedRoute( - this.path, this.pathTemplate, this.parameters, this.queryParameters); - - @override - bool operator ==(Object other) => - other is ParsedRoute && - other.pathTemplate == pathTemplate && - other.path == path && - _mapEquality.equals(parameters, other.parameters) && - _mapEquality.equals(queryParameters, other.queryParameters); - - @override - int get hashCode => hash4( - path, - pathTemplate, - _mapEquality.hash(parameters), - _mapEquality.hash(queryParameters), - ); - - @override - String toString() => ''; -} diff --git a/lib/13/go/raw_book/src/routing/parser.dart b/lib/13/go/raw_book/src/routing/parser.dart deleted file mode 100644 index fb25607..0000000 --- a/lib/13/go/raw_book/src/routing/parser.dart +++ /dev/null @@ -1,62 +0,0 @@ -// 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 'package:path_to_regexp/path_to_regexp.dart'; - -import 'parsed_route.dart'; - -/// Used by [TemplateRouteParser] to guard access to routes. -typedef RouteGuard = Future Function(T from); - -/// Parses the URI path into a [ParsedRoute]. -class TemplateRouteParser extends RouteInformationParser { - final List _pathTemplates; - final ParsedRoute initialRoute; - - TemplateRouteParser({ - /// The list of allowed path templates (['/', '/users/:id']) - required List allowedPaths, - - /// The initial route - String initialRoute = '/', - - }) : initialRoute = ParsedRoute(initialRoute, initialRoute, {}, {}), - _pathTemplates = [ - ...allowedPaths, - ], - assert(allowedPaths.contains(initialRoute)); - - @override - Future parseRouteInformation( - RouteInformation routeInformation, - ) async { - print("=======parseRouteInformation:${routeInformation.uri.path}==================="); - - final uri = routeInformation.uri; - final path = uri.toString(); - final queryParams = uri.queryParameters; - var parsedRoute = initialRoute; - - for (var pathTemplate in _pathTemplates) { - final parameters = []; - var pathRegExp = pathToRegExp(pathTemplate, parameters: parameters); - if (pathRegExp.hasMatch(path)) { - final match = pathRegExp.matchAsPrefix(path); - if (match == null) continue; - final params = extract(parameters, match); - parsedRoute = ParsedRoute(path, pathTemplate, params, queryParams); - } - } - - return parsedRoute; - } - - @override - RouteInformation restoreRouteInformation(ParsedRoute configuration) { - print("=======restoreRouteInformation:${configuration}==================="); - - return RouteInformation(uri: Uri.parse(configuration.path)); - } -} diff --git a/lib/13/go/raw_book/src/routing/route_state.dart b/lib/13/go/raw_book/src/routing/route_state.dart deleted file mode 100644 index aa7e1ad..0000000 --- a/lib/13/go/raw_book/src/routing/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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 TemplateRouteParser _parser; - ParsedRoute _route; - - RouteState(this._parser) : _route = _parser.initialRoute; - - 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/go/raw_book/src/screens/author_details.dart b/lib/13/go/raw_book/src/screens/author_details.dart deleted file mode 100644 index d45f861..0000000 --- a/lib/13/go/raw_book/src/screens/author_details.dart +++ /dev/null @@ -1,39 +0,0 @@ -// 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'; - -import '../data.dart'; -import '../routing.dart'; -import '../widgets/book_list.dart'; - -class AuthorDetailsScreen extends StatelessWidget { - final Author author; - - const AuthorDetailsScreen({ - super.key, - required this.author, - }); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: Text(author.name), - ), - body: Center( - child: Column( - children: [ - Expanded( - child: BookList( - books: author.books, - onTap: (book) { - RouteStateScope.of(context).go('/book/${book.id}'); - }, - ), - ), - ], - ), - ), - ); -} diff --git a/lib/13/go/raw_book/src/screens/authors.dart b/lib/13/go/raw_book/src/screens/authors.dart deleted file mode 100644 index 8965f91..0000000 --- a/lib/13/go/raw_book/src/screens/authors.dart +++ /dev/null @@ -1,28 +0,0 @@ -// 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'; - -import '../data/library.dart'; -import '../routing.dart'; -import '../widgets/author_list.dart'; - -class AuthorsScreen extends StatelessWidget { - final String title = 'Authors'; - - const AuthorsScreen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: Text(title), - ), - body: AuthorList( - authors: libraryInstance.allAuthors, - onTap: (author) { - RouteStateScope.of(context).go('/author/${author.id}'); - }, - ), - ); -} diff --git a/lib/13/go/raw_book/src/screens/book_details.dart b/lib/13/go/raw_book/src/screens/book_details.dart deleted file mode 100644 index 72a9346..0000000 --- a/lib/13/go/raw_book/src/screens/book_details.dart +++ /dev/null @@ -1,66 +0,0 @@ -// 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'; -import 'package:url_launcher/link.dart'; - -import '../data.dart'; -import 'author_details.dart'; - -class BookDetailsScreen extends StatelessWidget { - final Book? book; - - const BookDetailsScreen({ - super.key, - this.book, - }); - - @override - Widget build(BuildContext context) { - if (book == null) { - return const Scaffold( - body: Center( - child: Text('No book found.'), - ), - ); - } - return Scaffold( - appBar: AppBar( - title: Text(book!.title), - ), - body: Center( - child: Column( - children: [ - Text( - book!.title, - style: Theme.of(context).textTheme.headlineMedium, - ), - Text( - book!.author.name, - style: Theme.of(context).textTheme.titleMedium, - ), - TextButton( - child: const Text('View author (Push)'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - AuthorDetailsScreen(author: book!.author), - ), - ); - }, - ), - Link( - uri: Uri.parse('/author/${book!.author.id}'), - builder: (context, followLink) => TextButton( - onPressed: followLink, - child: const Text('View author (Link)'), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/13/go/raw_book/src/screens/books.dart b/lib/13/go/raw_book/src/screens/books.dart deleted file mode 100644 index 2646f1a..0000000 --- a/lib/13/go/raw_book/src/screens/books.dart +++ /dev/null @@ -1,111 +0,0 @@ -// 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'; - -import '../data.dart'; -import '../routing.dart'; -import '../widgets/book_list.dart'; - -class BooksScreen extends StatefulWidget { - const BooksScreen({ - super.key, - }); - - @override - State createState() => _BooksScreenState(); -} - -class _BooksScreenState extends State - with SingleTickerProviderStateMixin { - late TabController _tabController; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 3, vsync: this) - ..addListener(_handleTabIndexChanged); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - - final newPath = _routeState.route.pathTemplate; - if (newPath.startsWith('/books/popular')) { - _tabController.index = 0; - } else if (newPath.startsWith('/books/new')) { - _tabController.index = 1; - } else if (newPath == '/books/all') { - _tabController.index = 2; - } - } - - @override - void dispose() { - _tabController.removeListener(_handleTabIndexChanged); - super.dispose(); - } - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text('Books'), - elevation: 8, - bottom: TabBar( - controller: _tabController, - tabs: const [ - Tab( - text: 'Popular', - icon: Icon(Icons.people), - ), - Tab( - text: 'New', - icon: Icon(Icons.new_releases), - ), - Tab( - text: 'All', - icon: Icon(Icons.list), - ), - ], - ), - ), - body: TabBarView( - controller: _tabController, - children: [ - BookList( - books: libraryInstance.popularBooks, - onTap: _handleBookTapped, - ), - BookList( - books: libraryInstance.newBooks, - onTap: _handleBookTapped, - ), - BookList( - books: libraryInstance.allBooks, - onTap: _handleBookTapped, - ), - ], - ), - ); - - RouteState get _routeState => RouteStateScope.of(context); - - void _handleBookTapped(Book book) { - _routeState.go('/book/${book.id}'); - } - - void _handleTabIndexChanged() { - switch (_tabController.index) { - case 1: - _routeState.go('/books/new'); - case 2: - _routeState.go('/books/all'); - case 0: - default: - _routeState.go('/books/popular'); - break; - } - } -} diff --git a/lib/13/go/raw_book/src/screens/navigator.dart b/lib/13/go/raw_book/src/screens/navigator.dart deleted file mode 100644 index cfa8e68..0000000 --- a/lib/13/go/raw_book/src/screens/navigator.dart +++ /dev/null @@ -1,108 +0,0 @@ -// 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:flutter/material.dart'; - -import '../auth.dart'; -import '../data.dart'; -import '../routing.dart'; -import '../screens/sign_in.dart'; -import '../widgets/fade_transition_page.dart'; -import 'author_details.dart'; -import 'book_details.dart'; -import 'scaffold.dart'; - -/// Builds the top-level navigator for the app. The pages to display are based -/// on the `routeState` that was parsed by the TemplateRouteParser. -class BookstoreNavigator extends StatefulWidget { - final GlobalKey navigatorKey; - - const BookstoreNavigator({ - required this.navigatorKey, - super.key, - }); - - @override - State createState() => _BookstoreNavigatorState(); -} - -class _BookstoreNavigatorState extends State { - final _signInKey = const ValueKey('Sign in'); - final _scaffoldKey = const ValueKey('App scaffold'); - final _bookDetailsKey = const ValueKey('Book details screen'); - final _authorDetailsKey = const ValueKey('Author details screen'); - - @override - Widget build(BuildContext context) { - final routeState = RouteStateScope.of(context); - final pathTemplate = routeState.route.pathTemplate; - - Book? selectedBook; - if (pathTemplate == '/book/:bookId') { - selectedBook = libraryInstance.allBooks.firstWhereOrNull( - (b) => b.id.toString() == routeState.route.parameters['bookId']); - } - - Author? selectedAuthor; - if (pathTemplate == '/author/:authorId') { - selectedAuthor = libraryInstance.allAuthors.firstWhereOrNull( - (b) => b.id.toString() == routeState.route.parameters['authorId']); - } - - return Navigator( - key: widget.navigatorKey, - onPopPage: (route, dynamic result) { - // When a page that is stacked on top of the scaffold is popped, display - // the /books or /authors tab in BookstoreScaffold. - if (route.settings is Page && - (route.settings as Page).key == _bookDetailsKey) { - routeState.go('/books/popular'); - } - - if (route.settings is Page && - (route.settings as Page).key == _authorDetailsKey) { - routeState.go('/authors'); - } - - return route.didPop(result); - }, - pages: [ - if (routeState.route.pathTemplate == '/signin') - // Display the sign in screen. - FadeTransitionPage( - key: _signInKey, - child: SignInScreen( - onSignIn: (credentials) async { - await routeState.go('/books/popular'); - }, - ), - ) - else ...[ - // Display the app - FadeTransitionPage( - key: _scaffoldKey, - child: const BookstoreScaffold(), - ), - // Add an additional page to the stack if the user is viewing a book - // or an author - if (selectedBook != null) - MaterialPage( - key: _bookDetailsKey, - child: BookDetailsScreen( - book: selectedBook, - ), - ) - else if (selectedAuthor != null) - MaterialPage( - key: _authorDetailsKey, - child: AuthorDetailsScreen( - author: selectedAuthor, - ), - ), - ], - ], - ); - } -} diff --git a/lib/13/go/raw_book/src/screens/scaffold.dart b/lib/13/go/raw_book/src/screens/scaffold.dart deleted file mode 100644 index 4949191..0000000 --- a/lib/13/go/raw_book/src/screens/scaffold.dart +++ /dev/null @@ -1,54 +0,0 @@ -// 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:adaptive_navigation/adaptive_navigation.dart'; -import 'package:flutter/material.dart'; - -import '../routing.dart'; -import 'scaffold_body.dart'; - -class BookstoreScaffold extends StatelessWidget { - const BookstoreScaffold({ - super.key, - }); - - @override - Widget build(BuildContext context) { - final routeState = RouteStateScope.of(context); - final selectedIndex = _getSelectedIndex(routeState.route.pathTemplate); - - return Scaffold( - body: AdaptiveNavigationScaffold( - selectedIndex: selectedIndex, - body: const BookstoreScaffoldBody(), - onDestinationSelected: (idx) { - if (idx == 0) routeState.go('/books/popular'); - if (idx == 1) routeState.go('/authors'); - if (idx == 2) routeState.go('/settings'); - }, - destinations: const [ - AdaptiveScaffoldDestination( - title: 'Books', - icon: Icons.book, - ), - AdaptiveScaffoldDestination( - title: 'Authors', - icon: Icons.person, - ), - AdaptiveScaffoldDestination( - title: 'Settings', - icon: Icons.settings, - ), - ], - ), - ); - } - - int _getSelectedIndex(String pathTemplate) { - if (pathTemplate.startsWith('/books')) return 0; - if (pathTemplate == '/authors') return 1; - if (pathTemplate == '/settings') return 2; - return 0; - } -} diff --git a/lib/13/go/raw_book/src/screens/scaffold_body.dart b/lib/13/go/raw_book/src/screens/scaffold_body.dart deleted file mode 100644 index 868e32e..0000000 --- a/lib/13/go/raw_book/src/screens/scaffold_body.dart +++ /dev/null @@ -1,63 +0,0 @@ -// 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'; - -import '../routing.dart'; -import '../screens/settings.dart'; -import '../widgets/fade_transition_page.dart'; -import 'authors.dart'; -import 'books.dart'; -import 'scaffold.dart'; - -/// Displays the contents of the body of [BookstoreScaffold] -class BookstoreScaffoldBody extends StatelessWidget { - static GlobalKey navigatorKey = GlobalKey(); - - const BookstoreScaffoldBody({ - super.key, - }); - - @override - Widget build(BuildContext context) { - var currentRoute = RouteStateScope.of(context).route; - - // A nested Router isn't necessary because the back button behavior doesn't - // need to be customized. - return Navigator( - key: navigatorKey, - onPopPage: (route, dynamic result) => route.didPop(result), - pages: [ - if (currentRoute.pathTemplate.startsWith('/authors')) - const FadeTransitionPage( - key: ValueKey('authors'), - child: AuthorsScreen(), - ) - else if (currentRoute.pathTemplate.startsWith('/settings')) - const FadeTransitionPage( - key: ValueKey('settings'), - child: SettingsScreen(), - ) - else if (currentRoute.pathTemplate.startsWith('/books') || - currentRoute.pathTemplate == '/') - const FadeTransitionPage( - key: ValueKey('books'), - child: BooksScreen(), - ) - - // Avoid building a Navigator with an empty `pages` list when the - // RouteState is set to an unexpected path, such as /signin. - // - // Since RouteStateScope is an InheritedNotifier, any change to the - // route will result in a call to this build method, even though this - // widget isn't built when those routes are active. - else - FadeTransitionPage( - key: const ValueKey('empty'), - child: Container(), - ), - ], - ); - } -} diff --git a/lib/13/go/raw_book/src/screens/settings.dart b/lib/13/go/raw_book/src/screens/settings.dart deleted file mode 100644 index cefd834..0000000 --- a/lib/13/go/raw_book/src/screens/settings.dart +++ /dev/null @@ -1,95 +0,0 @@ -// 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'; -import 'package:url_launcher/link.dart'; - -import '../auth.dart'; -import '../routing.dart'; - -class SettingsScreen extends StatefulWidget { - const SettingsScreen({super.key}); - - @override - State createState() => _SettingsScreenState(); -} - -class _SettingsScreenState extends State { - @override - Widget build(BuildContext context) => Scaffold( - body: SafeArea( - child: SingleChildScrollView( - child: Align( - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 400), - child: const Card( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12), - child: SettingsContent(), - ), - ), - ), - ), - ), - ), - ); -} - -class SettingsContent extends StatelessWidget { - const SettingsContent({ - super.key, - }); - - @override - Widget build(BuildContext context) => Column( - children: [ - ...[ - Text( - 'Settings', - style: Theme.of(context).textTheme.headlineMedium, - ), - FilledButton( - onPressed: () { - // BookstoreAuthScope.of(context).signOut(); - }, - child: const Text('Sign out'), - ), - Link( - uri: Uri.parse('/book/0'), - builder: (context, followLink) => TextButton( - onPressed: followLink, - child: const Text('Go directly to /book/0 (Link)'), - ), - ), - TextButton( - child: const Text('Go directly to /book/0 (RouteState)'), - onPressed: () { - RouteStateScope.of(context).go('/book/0'); - }, - ), - ].map((w) => Padding(padding: const EdgeInsets.all(8), child: w)), - TextButton( - onPressed: () => showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('Alert!'), - content: const Text('The alert description goes here.'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, 'Cancel'), - child: const Text('Cancel'), - ), - TextButton( - onPressed: () => Navigator.pop(context, 'OK'), - child: const Text('OK'), - ), - ], - ), - ), - child: const Text('Show Dialog'), - ) - ], - ); -} diff --git a/lib/13/go/raw_book/src/screens/sign_in.dart b/lib/13/go/raw_book/src/screens/sign_in.dart deleted file mode 100644 index 84f915f..0000000 --- a/lib/13/go/raw_book/src/screens/sign_in.dart +++ /dev/null @@ -1,69 +0,0 @@ -// 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 Credentials { - final String username; - final String password; - - Credentials(this.username, this.password); -} - -class SignInScreen extends StatefulWidget { - final ValueChanged onSignIn; - - const SignInScreen({ - required this.onSignIn, - super.key, - }); - - @override - State createState() => _SignInScreenState(); -} - -class _SignInScreenState extends State { - final _usernameController = TextEditingController(); - final _passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) => Scaffold( - body: Center( - child: Card( - child: Container( - constraints: BoxConstraints.loose(const Size(600, 600)), - padding: const EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text('Sign in', - style: Theme.of(context).textTheme.headlineMedium), - TextField( - decoration: const InputDecoration(labelText: 'Username'), - controller: _usernameController, - ), - TextField( - decoration: const InputDecoration(labelText: 'Password'), - obscureText: true, - controller: _passwordController, - ), - Padding( - padding: const EdgeInsets.all(16), - child: TextButton( - onPressed: () async { - widget.onSignIn(Credentials( - _usernameController.value.text, - _passwordController.value.text)); - }, - child: const Text('Sign in'), - ), - ), - ], - ), - ), - ), - ), - ); -} diff --git a/lib/13/go/raw_book/src/widgets/author_list.dart b/lib/13/go/raw_book/src/widgets/author_list.dart deleted file mode 100644 index 8890696..0000000 --- a/lib/13/go/raw_book/src/widgets/author_list.dart +++ /dev/null @@ -1,32 +0,0 @@ -// 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'; - -import '../data.dart'; - -class AuthorList extends StatelessWidget { - final List authors; - final ValueChanged? onTap; - - const AuthorList({ - required this.authors, - this.onTap, - super.key, - }); - - @override - Widget build(BuildContext context) => ListView.builder( - itemCount: authors.length, - itemBuilder: (context, index) => ListTile( - title: Text( - authors[index].name, - ), - subtitle: Text( - '${authors[index].books.length} books', - ), - onTap: onTap != null ? () => onTap!(authors[index]) : null, - ), - ); -} diff --git a/lib/13/go/raw_book/src/widgets/book_list.dart b/lib/13/go/raw_book/src/widgets/book_list.dart deleted file mode 100644 index b3c6370..0000000 --- a/lib/13/go/raw_book/src/widgets/book_list.dart +++ /dev/null @@ -1,32 +0,0 @@ -// 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'; - -import '../data.dart'; - -class BookList extends StatelessWidget { - final List books; - final ValueChanged? onTap; - - const BookList({ - required this.books, - this.onTap, - super.key, - }); - - @override - Widget build(BuildContext context) => ListView.builder( - itemCount: books.length, - itemBuilder: (context, index) => ListTile( - title: Text( - books[index].title, - ), - subtitle: Text( - books[index].author.name, - ), - onTap: onTap != null ? () => onTap!(books[index]) : null, - ), - ); -} diff --git a/lib/13/go/redirection.dart b/lib/13/go/redirection.dart deleted file mode 100644 index aded4b7..0000000 --- a/lib/13/go/redirection.dart +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; -import 'package:provider/provider.dart'; - -// This scenario demonstrates how to use redirect to handle a sign-in flow. -// -// The GoRouter.redirect method is called before the app is navigate to a -// new page. You can choose to redirect to a different page by returning a -// non-null URL string. - -/// The login information. -class LoginInfo extends ChangeNotifier { - /// The username of login. - String get userName => _userName; - String _userName = ''; - - /// Whether a user has logged in. - bool get loggedIn => _userName.isNotEmpty; - - /// Logs in a user. - void login(String userName) { - _userName = userName; - notifyListeners(); - } - - /// Logs out the current user. - void logout() { - _userName = ''; - notifyListeners(); - } -} - -void main() => runApp(App()); - -/// The main app. -class App extends StatelessWidget { - /// Creates an [App]. - App({super.key}); - - final LoginInfo _loginInfo = LoginInfo(); - - /// The title of the app. - static const String title = 'GoRouter Example: Redirection'; - - // add the login info into the tree as app state that can change over time - @override - Widget build(BuildContext context) => ChangeNotifierProvider.value( - value: _loginInfo, - child: MaterialApp.router( - routerConfig: _router, - title: title, - debugShowCheckedModeBanner: false, - ), - ); - - late final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) => - const HomeScreen(), - ), - GoRoute( - path: '/login', - builder: (BuildContext context, GoRouterState state) => - const LoginScreen(), - ), - ], - - // redirect to the login page if the user is not logged in - redirect: (BuildContext context, GoRouterState state) { - // if the user is not logged in, they need to login - final bool loggedIn = _loginInfo.loggedIn; - final bool loggingIn = state.matchedLocation == '/login'; - if (!loggedIn) { - return '/login'; - } - - // if the user is logged in but still on the login page, send them to - // the home page - if (loggingIn) { - return '/'; - } - - // no need to redirect at all - return null; - }, - - // changes on the listenable will cause the router to refresh it's route - refreshListenable: _loginInfo, - ); -} - -/// The login screen. -class LoginScreen extends StatelessWidget { - /// Creates a [LoginScreen]. - const LoginScreen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar(title: const Text(App.title)), - body: Center( - child: ElevatedButton( - onPressed: () { - // log a user in, letting all the listeners know - context.read().login('test-user'); - - // router will automatically redirect from /login to / using - // refreshListenable - }, - child: const Text('Login'), - ), - ), - ); -} - -/// The home screen. -class HomeScreen extends StatelessWidget { - /// Creates a [HomeScreen]. - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - final LoginInfo info = context.read(); - - return Scaffold( - appBar: AppBar( - title: const Text(App.title), - actions: [ - IconButton( - onPressed: info.logout, - tooltip: 'Logout: ${info.userName}', - icon: const Icon(Icons.logout), - ) - ], - ), - body: const Center( - child: Text('HomeScreen'), - ), - ); - } -} diff --git a/lib/13/go/shell_route.dart b/lib/13/go/shell_route.dart deleted file mode 100644 index 70878b8..0000000 --- a/lib/13/go/shell_route.dart +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -final GlobalKey _rootNavigatorKey = - GlobalKey(debugLabel: 'root'); -final GlobalKey _shellNavigatorKey = - GlobalKey(debugLabel: 'shell'); - -// This scenario demonstrates how to set up nested navigation using ShellRoute, -// which is a pattern where an additional Navigator is placed in the widget tree -// to be used instead of the root navigator. This allows deep-links to display -// pages along with other UI components such as a BottomNavigationBar. -// -// This example demonstrates how to display a route within a ShellRoute and also -// push a screen using a different navigator (such as the root Navigator) by -// providing a `parentNavigatorKey`. - -void main() { - runApp(ShellRouteExampleApp()); -} - -/// An example demonstrating how to use [ShellRoute] -class ShellRouteExampleApp extends StatelessWidget { - /// Creates a [ShellRouteExampleApp] - ShellRouteExampleApp({super.key}); - - final GoRouter _router = GoRouter( - navigatorKey: _rootNavigatorKey, - initialLocation: '/a', - debugLogDiagnostics: true, - routes: [ - /// Application shell - ShellRoute( - navigatorKey: _shellNavigatorKey, - builder: (BuildContext context, GoRouterState state, Widget child) { - return ScaffoldWithNavBar(child: child); - }, - routes: [ - /// The first screen to display in the bottom navigation bar. - GoRoute( - path: '/a', - builder: (BuildContext context, GoRouterState state) { - return const ScreenA(); - }, - routes: [ - // The details screen to display stacked on the inner Navigator. - // This will cover screen A but not the application shell. - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) { - return const DetailsScreen(label: 'A'); - }, - ), - ], - ), - - /// Displayed when the second item in the the bottom navigation bar is - /// selected. - GoRoute( - path: '/b', - builder: (BuildContext context, GoRouterState state) { - return const ScreenB(); - }, - routes: [ - /// Same as "/a/details", but displayed on the root Navigator by - /// specifying [parentNavigatorKey]. This will cover both screen B - /// and the application shell. - GoRoute( - path: 'details', - parentNavigatorKey: _rootNavigatorKey, - builder: (BuildContext context, GoRouterState state) { - return const DetailsScreen(label: 'B'); - }, - ), - ], - ), - - /// The third screen to display in the bottom navigation bar. - GoRoute( - path: '/c', - builder: (BuildContext context, GoRouterState state) { - return const ScreenC(); - }, - routes: [ - // The details screen to display stacked on the inner Navigator. - // This will cover screen A but not the application shell. - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) { - return const DetailsScreen(label: 'C'); - }, - ), - ], - ), - ], - ), - ], - ); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - routerConfig: _router, - ); - } -} - -/// Builds the "shell" for the app by building a Scaffold with a -/// BottomNavigationBar, where [child] is placed in the body of the Scaffold. -class ScaffoldWithNavBar extends StatelessWidget { - /// Constructs an [ScaffoldWithNavBar]. - const ScaffoldWithNavBar({ - required this.child, - super.key, - }); - - /// The widget to display in the body of the Scaffold. - /// In this sample, it is a Navigator. - final Widget child; - - @override - Widget build(BuildContext context) { - return Scaffold( - body: child, - bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'A Screen', - ), - BottomNavigationBarItem( - icon: Icon(Icons.business), - label: 'B Screen', - ), - BottomNavigationBarItem( - icon: Icon(Icons.notification_important_rounded), - label: 'C Screen', - ), - ], - currentIndex: _calculateSelectedIndex(context), - onTap: (int idx) => _onItemTapped(idx, context), - ), - ); - } - - static int _calculateSelectedIndex(BuildContext context) { - final String location = GoRouterState.of(context).uri.toString(); - if (location.startsWith('/a')) { - return 0; - } - if (location.startsWith('/b')) { - return 1; - } - if (location.startsWith('/c')) { - return 2; - } - return 0; - } - - void _onItemTapped(int index, BuildContext context) { - switch (index) { - case 0: - GoRouter.of(context).go('/a'); - break; - case 1: - GoRouter.of(context).go('/b'); - break; - case 2: - GoRouter.of(context).go('/c'); - break; - } - } -} - -/// The first screen in the bottom navigation bar. -class ScreenA extends StatelessWidget { - /// Constructs a [ScreenA] widget. - const ScreenA({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Screen A'), - TextButton( - onPressed: () { - GoRouter.of(context).go('/a/details'); - }, - child: const Text('View A details'), - ), - ], - ), - ), - ); - } -} - -/// The second screen in the bottom navigation bar. -class ScreenB extends StatelessWidget { - /// Constructs a [ScreenB] widget. - const ScreenB({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Screen B'), - TextButton( - onPressed: () { - GoRouter.of(context).go('/b/details'); - }, - child: const Text('View B details'), - ), - ], - ), - ), - ); - } -} - -/// The third screen in the bottom navigation bar. -class ScreenC extends StatelessWidget { - /// Constructs a [ScreenC] widget. - const ScreenC({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Screen C'), - TextButton( - onPressed: () { - GoRouter.of(context).go('/c/details'); - }, - child: const Text('View C details'), - ), - ], - ), - ), - ); - } -} - -/// The details screen for either the A, B or C screen. -class DetailsScreen extends StatelessWidget { - /// Constructs a [DetailsScreen]. - const DetailsScreen({ - required this.label, - super.key, - }); - - /// The label to display in the center of the screen. - final String label; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Details Screen'), - ), - body: Center( - child: Text( - 'Details for $label', - style: Theme.of(context).textTheme.headlineMedium, - ), - ), - ); - } -} diff --git a/lib/13/go/stateful_shell_route.dart b/lib/13/go/stateful_shell_route.dart deleted file mode 100644 index eb0a67b..0000000 --- a/lib/13/go/stateful_shell_route.dart +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -final GlobalKey _rootNavigatorKey = - GlobalKey(debugLabel: 'root'); -final GlobalKey _sectionANavigatorKey = - GlobalKey(debugLabel: 'sectionANav'); - -// This example demonstrates how to setup nested navigation using a -// BottomNavigationBar, where each bar item uses its own persistent navigator, -// i.e. navigation state is maintained separately for each item. This setup also -// enables deep linking into nested pages. - -void main() { - runApp(NestedTabNavigationExampleApp()); -} - -/// An example demonstrating how to use nested navigators -class NestedTabNavigationExampleApp extends StatelessWidget { - /// Creates a NestedTabNavigationExampleApp - NestedTabNavigationExampleApp({super.key}); - - final GoRouter _router = GoRouter( - navigatorKey: _rootNavigatorKey, - initialLocation: '/a', - routes: [ - StatefulShellRoute.indexedStack( - builder: (BuildContext context, GoRouterState state, - StatefulNavigationShell navigationShell) { - // Return the widget that implements the custom shell (in this case - // using a BottomNavigationBar). The StatefulNavigationShell is passed - // to be able access the state of the shell and to navigate to other - // branches in a stateful way. - return ScaffoldWithNavBar(navigationShell: navigationShell); - }, - branches: [ - // The route branch for the first tab of the bottom navigation bar. - StatefulShellBranch( - navigatorKey: _sectionANavigatorKey, - routes: [ - GoRoute( - // The screen to display as the root in the first tab of the - // bottom navigation bar. - path: '/a', - builder: (BuildContext context, GoRouterState state) => - const RootScreen(label: 'A', detailsPath: '/a/details'), - routes: [ - // The details screen to display stacked on navigator of the - // first tab. This will cover screen A but not the application - // shell (bottom navigation bar). - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) => - const DetailsScreen(label: 'A'), - ), - ], - ), - ], - ), - - // The route branch for the second tab of the bottom navigation bar. - StatefulShellBranch( - // It's not necessary to provide a navigatorKey if it isn't also - // needed elsewhere. If not provided, a default key will be used. - routes: [ - GoRoute( - // The screen to display as the root in the second tab of the - // bottom navigation bar. - path: '/b', - builder: (BuildContext context, GoRouterState state) => - const RootScreen( - label: 'B', - detailsPath: '/b/details/1', - secondDetailsPath: '/b/details/2', - ), - routes: [ - GoRoute( - path: 'details/:param', - builder: (BuildContext context, GoRouterState state) => - DetailsScreen( - label: 'B', - param: state.pathParameters['param'], - ), - ), - ], - ), - ], - ), - - // The route branch for the third tab of the bottom navigation bar. - StatefulShellBranch( - routes: [ - GoRoute( - // The screen to display as the root in the third tab of the - // bottom navigation bar. - path: '/c', - builder: (BuildContext context, GoRouterState state) => - const RootScreen( - label: 'C', - detailsPath: '/c/details', - ), - routes: [ - GoRoute( - path: 'details', - builder: (BuildContext context, GoRouterState state) => - DetailsScreen( - label: 'C', - extra: state.extra, - ), - ), - ], - ), - ], - ), - ], - ), - ], - ); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - routerConfig: _router, - ); - } -} - -/// Builds the "shell" for the app by building a Scaffold with a -/// BottomNavigationBar, where [child] is placed in the body of the Scaffold. -class ScaffoldWithNavBar extends StatelessWidget { - /// Constructs an [ScaffoldWithNavBar]. - const ScaffoldWithNavBar({ - required this.navigationShell, - Key? key, - }) : super(key: key ?? const ValueKey('ScaffoldWithNavBar')); - - /// The navigation shell and container for the branch Navigators. - final StatefulNavigationShell navigationShell; - - @override - Widget build(BuildContext context) { - return Scaffold( - body: navigationShell, - bottomNavigationBar: BottomNavigationBar( - // Here, the items of BottomNavigationBar are hard coded. In a real - // world scenario, the items would most likely be generated from the - // branches of the shell route, which can be fetched using - // `navigationShell.route.branches`. - items: const [ - BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'), - BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'), - BottomNavigationBarItem(icon: Icon(Icons.tab), label: 'Section C'), - ], - currentIndex: navigationShell.currentIndex, - onTap: (int index) => _onTap(context, index), - ), - ); - } - - /// Navigate to the current location of the branch at the provided index when - /// tapping an item in the BottomNavigationBar. - void _onTap(BuildContext context, int index) { - // When navigating to a new branch, it's recommended to use the goBranch - // method, as doing so makes sure the last navigation state of the - // Navigator for the branch is restored. - navigationShell.goBranch( - index, - // A common pattern when using bottom navigation bars is to support - // navigating to the initial location when tapping the item that is - // already active. This example demonstrates how to support this behavior, - // using the initialLocation parameter of goBranch. - initialLocation: index == navigationShell.currentIndex, - ); - } -} - -/// Widget for the root/initial pages in the bottom navigation bar. -class RootScreen extends StatelessWidget { - /// Creates a RootScreen - const RootScreen({ - required this.label, - required this.detailsPath, - this.secondDetailsPath, - super.key, - }); - - /// The label - final String label; - - /// The path to the detail page - final String detailsPath; - - /// The path to another detail page - final String? secondDetailsPath; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('Root of section $label'), - ), - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Screen $label', - style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - GoRouter.of(context).go(detailsPath, extra: '$label-XYZ'); - }, - child: const Text('View details'), - ), - const Padding(padding: EdgeInsets.all(4)), - if (secondDetailsPath != null) - TextButton( - onPressed: () { - GoRouter.of(context).go(secondDetailsPath!); - }, - child: const Text('View more details'), - ), - ], - ), - ), - ); - } -} - -/// The details screen for either the A or B screen. -class DetailsScreen extends StatefulWidget { - /// Constructs a [DetailsScreen]. - const DetailsScreen({ - required this.label, - this.param, - this.extra, - this.withScaffold = true, - super.key, - }); - - /// The label to display in the center of the screen. - final String label; - - /// Optional param - final String? param; - - /// Optional extra object - final Object? extra; - - /// Wrap in scaffold - final bool withScaffold; - - @override - State createState() => DetailsScreenState(); -} - -/// The state for DetailsScreen -class DetailsScreenState extends State { - int _counter = 0; - - @override - Widget build(BuildContext context) { - if (widget.withScaffold) { - return Scaffold( - appBar: AppBar( - title: Text('Details Screen - ${widget.label}'), - ), - body: _build(context), - ); - } else { - return Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: _build(context), - ); - } - } - - Widget _build(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Details for ${widget.label} - Counter: $_counter', - style: Theme.of(context).textTheme.titleLarge), - const Padding(padding: EdgeInsets.all(4)), - TextButton( - onPressed: () { - setState(() { - _counter++; - }); - }, - child: const Text('Increment counter'), - ), - const Padding(padding: EdgeInsets.all(8)), - if (widget.param != null) - Text('Parameter: ${widget.param!}', - style: Theme.of(context).textTheme.titleMedium), - const Padding(padding: EdgeInsets.all(8)), - if (widget.extra != null) - Text('Extra: ${widget.extra!}', - style: Theme.of(context).textTheme.titleMedium), - if (!widget.withScaffold) ...[ - const Padding(padding: EdgeInsets.all(16)), - TextButton( - onPressed: () { - GoRouter.of(context).pop(); - }, - child: const Text('< Back', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), - ), - ] - ], - ), - ); - } -} diff --git a/lib/13/go/transition_animations.dart b/lib/13/go/transition_animations.dart deleted file mode 100644 index f245719..0000000 --- a/lib/13/go/transition_animations.dart +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2013 The Flutter Authors. 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'; -import 'package:go_router/go_router.dart'; - -/// To use a custom transition animation, provide a `pageBuilder` with a -/// CustomTransitionPage. -/// -/// To learn more about animation in Flutter, check out the [Introduction to -/// animations](https://docs.flutter.dev/development/ui/animations) page on -/// flutter.dev. -void main() => runApp(const MyApp()); - -/// The route configuration. -final GoRouter _router = GoRouter( - routes: [ - GoRoute( - path: '/', - builder: (BuildContext context, GoRouterState state) { - return const HomeScreen(); - }, - routes: [ - GoRoute( - path: 'details', - pageBuilder: (BuildContext context, GoRouterState state) { - return CustomTransitionPage( - key: state.pageKey, - child: const DetailsScreen(), - transitionDuration: const Duration(milliseconds: 150), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) { - // Change the opacity of the screen using a Curve based on the the animation's - // value - return FadeTransition( - opacity: - CurveTween(curve: Curves.easeInOut).animate(animation), - child: child, - ); - }, - ); - }, - ), - GoRoute( - path: 'dismissible-details', - pageBuilder: (BuildContext context, GoRouterState state) { - return CustomTransitionPage( - key: state.pageKey, - child: const DismissibleDetails(), - barrierDismissible: true, - barrierColor: Colors.black38, - opaque: false, - transitionDuration: Duration.zero, - transitionsBuilder: (_, __, ___, Widget child) => child, - ); - }, - ), - GoRoute( - path: 'custom-reverse-transition-duration', - pageBuilder: (BuildContext context, GoRouterState state) { - return CustomTransitionPage( - key: state.pageKey, - child: const DetailsScreen(), - barrierDismissible: true, - barrierColor: Colors.black38, - opaque: false, - transitionDuration: const Duration(milliseconds: 500), - reverseTransitionDuration: const Duration(milliseconds: 200), - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) { - return FadeTransition( - opacity: animation, - child: child, - ); - }, - ); - }, - ), - ], - ), - ], -); - -/// The main app. -class MyApp extends StatelessWidget { - /// Constructs a [MyApp] - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - routerConfig: _router, - ); - } -} - -/// The home screen -class HomeScreen extends StatelessWidget { - /// Constructs a [HomeScreen] - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Home Screen')), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/details'), - child: const Text('Go to the Details screen'), - ), - const SizedBox(height: 48), - ElevatedButton( - onPressed: () => context.go('/dismissible-details'), - child: const Text('Go to the Dismissible Details screen'), - ), - const SizedBox(height: 48), - ElevatedButton( - onPressed: () => - context.go('/custom-reverse-transition-duration'), - child: const Text( - 'Go to the Custom Reverse Transition Duration Screen', - ), - ), - ], - ), - ), - ); - } -} - -/// The details screen -class DetailsScreen extends StatelessWidget { - /// Constructs a [DetailsScreen] - const DetailsScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Details Screen')), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => context.go('/'), - child: const Text('Go back to the Home screen'), - ), - ], - ), - ), - ); - } -} - -/// The dismissible details screen -class DismissibleDetails extends StatelessWidget { - /// Constructs a [DismissibleDetails] - const DismissibleDetails({super.key}); - - @override - Widget build(BuildContext context) { - return const Padding( - padding: EdgeInsets.all(48), - child: ColoredBox(color: Colors.red), - ); - } -} diff --git a/lib/13/go_color/main.dart b/lib/13/go_color/main.dart deleted file mode 100644 index b396b4e..0000000 --- a/lib/13/go_color/main.dart +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 3b8ecca..0000000 --- a/lib/13/go_color/pages/app.dart +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index bee43b4..0000000 --- a/lib/13/go_color/pages/color_add_page.dart +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 6ed198f..0000000 --- a/lib/13/go_color/pages/home_page.dart +++ /dev/null @@ -1,61 +0,0 @@ -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 deleted file mode 100644 index ea47fee..0000000 --- a/lib/13/go_color/route/parsed_route.dart +++ /dev/null @@ -1,21 +0,0 @@ -// // 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 deleted file mode 100644 index e6d2bdf..0000000 --- a/lib/13/go_color/route/parser.dart +++ /dev/null @@ -1,112 +0,0 @@ -// 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 deleted file mode 100644 index 584bec8..0000000 --- a/lib/13/go_color/route/route_state.dart +++ /dev/null @@ -1,48 +0,0 @@ -// // 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/节点介绍.txt b/lib/13/节点介绍.txt deleted file mode 100644 index 7897938..0000000 --- a/lib/13/节点介绍.txt +++ /dev/null @@ -1,6 +0,0 @@ -01: Router#RouterDelegate 基础使用 - 改造基于数据控制 A、B、C 三个界面跳转。 - -02: 导航 2.0 中返回操作介绍 - -03: 侧栏菜单导航 V1 \ No newline at end of file diff --git a/lib/14/01/app/navigation/views/app_navigation_rail.dart b/lib/14/01/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 2899ea2..0000000 --- a/lib/14/01/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List 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(() { - - }); - } -} \ No newline at end of file diff --git a/lib/14/01/app/unit_app.dart b/lib/14/01/app/unit_app.dart deleted file mode 100644 index 5332b5d..0000000 --- a/lib/14/01/app/unit_app.dart +++ /dev/null @@ -1,38 +0,0 @@ -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(), - ), - ), - ], - ), - )); - } -} - - diff --git a/lib/14/01/main.dart b/lib/14/01/main.dart deleted file mode 100644 index 38c9d78..0000000 --- a/lib/14/01/main.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app/unit_app.dart'; -import 'app/navigation/app_router_delegate.dart'; - - - - - -void main() { - runApp(const UnitApp()); -} - - - - diff --git a/lib/14/01/pages/color/color_add_page.dart b/lib/14/01/pages/color/color_add_page.dart deleted file mode 100644 index b3cf660..0000000 --- a/lib/14/01/pages/color/color_add_page.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.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( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - 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), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - 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); - } - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/14/01/pages/color/color_page.dart b/lib/14/01/pages/color/color_page.dart deleted file mode 100644 index 9c8ca6d..0000000 --- a/lib/14/01/pages/color/color_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/common/components/colors_panel.dart'; -import '../../app/navigation/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState 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); - router.path = '/color/detail?color=$value'; - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/14/01/pages/empty/empty_page.dart b/lib/14/01/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/14/01/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -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), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/14/01/transition/fade_transition_page.dart b/lib/14/01/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/14/01/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// 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 extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _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 animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/14/02/app/navigation/router/iroute.dart b/lib/14/02/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/14/02/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/14/02/main.dart b/lib/14/02/main.dart deleted file mode 100644 index ec1745c..0000000 --- a/lib/14/02/main.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:window_manager/window_manager.dart'; - -import 'app/unit_app.dart'; -import 'app/navigation/router/app_router_delegate.dart'; - - -void main() { - WidgetsFlutterBinding.ensureInitialized(); - setSize(); - runApp(const UnitApp()); -} - - -void setSize() async{ - await windowManager.ensureInitialized(); - WindowOptions windowOptions = const WindowOptions( - size: Size(800, 540), - center: true, - backgroundColor: Colors.transparent, - skipTaskbar: false, - titleBarStyle: TitleBarStyle.hidden, - ); - windowManager.waitUntilReadyToShow(windowOptions, () async { - await windowManager.show(); - await windowManager.focus(); - }); -} diff --git a/lib/14/02/pages/counter/counter_page.dart b/lib/14/02/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/14/02/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - 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), - ), - ); - } -} \ No newline at end of file diff --git a/lib/14/02/pages/empty/empty_page.dart b/lib/14/02/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/14/02/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -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), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/14/02/pages/settings/settings_page.dart b/lib/14/02/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/14/02/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -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'))); - } -} diff --git a/lib/14/02/pages/user/user_page.dart b/lib/14/02/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/14/02/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -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'))); - } -} diff --git a/lib/14/02/transition/fade_transition_page.dart b/lib/14/02/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/14/02/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// 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 extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _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 animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/14/02/transition/no_transition_page.dart b/lib/14/02/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/14/02/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// 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 extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _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 animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/cases/cases.dart b/lib/cases/cases.dart deleted file mode 100644 index 3f5d5e3..0000000 --- a/lib/cases/cases.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'counter/counter_page.dart'; -export 'guess/guess_page.dart'; -export 'paper/paper.dart'; \ No newline at end of file diff --git a/lib/cases/counter/counter_page.dart b/lib/cases/counter/counter_page.dart deleted file mode 100644 index 039b571..0000000 --- a/lib/cases/counter/counter_page.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - 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), - ), - ); - } -} \ No newline at end of file diff --git a/lib/cases/guess/guess_app_bar.dart b/lib/cases/guess/guess_app_bar.dart deleted file mode 100644 index ee4bf94..0000000 --- a/lib/cases/guess/guess_app_bar.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class GuessAppBar extends StatelessWidget implements PreferredSizeWidget { - final VoidCallback onCheck; - final TextEditingController controller; - - const GuessAppBar({ - Key? key, - required this.onCheck, - required this.controller, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return AppBar( - leading: Icon(Icons.menu, color: Colors.black), - actions: [ - IconButton( - splashRadius: 20, - onPressed: onCheck, - icon: Icon( - Icons.run_circle_outlined, - color: Colors.blue, - )) - ], - title: TextField( - controller: controller, - keyboardType: TextInputType.number, - 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: "输入 0~99 数字", - hintStyle: TextStyle(fontSize: 14)), - ), - ); - } - - @override - Size get preferredSize => const Size.fromHeight(kToolbarHeight); -} diff --git a/lib/cases/guess/guess_page.dart b/lib/cases/guess/guess_page.dart deleted file mode 100644 index 2d0b994..0000000 --- a/lib/cases/guess/guess_page.dart +++ /dev/null @@ -1,125 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'guess_app_bar.dart'; -import 'result_notice.dart'; - -class GuessPage extends StatefulWidget { - const GuessPage({super.key}); - - @override - State createState() => _GuessPageState(); -} - -class _GuessPageState extends State with SingleTickerProviderStateMixin,AutomaticKeepAliveClientMixin{ - - late AnimationController controller; - - @override - void initState() { - super.initState(); - controller = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 200), - ); - } - - - int _value = 0; - - final Random _random = Random(); - bool _guessing = false; - bool? _isBig; - - - @override - void dispose() { - _guessCtrl.dispose(); - controller.dispose(); - super.dispose(); - } - - void _generateRandomValue() { - setState(() { - _guessing = true; - _value = _random.nextInt(100); - print(_value); - }); - } - - TextEditingController _guessCtrl = TextEditingController(); - - void _onCheck() { - print("=====Check:目标数值:$_value=====${_guessCtrl.text}============"); - int? guessValue = int.tryParse(_guessCtrl.text); - // 游戏未开始,或者输入非整数,无视 - if (!_guessing || guessValue == null) return; - controller.forward(from: 0); - //猜对了 - if (guessValue == _value) { - setState(() { - _isBig = null; - _guessing = false; - }); - return; - } - // 猜错了 - setState(() { - _isBig = guessValue > _value; - }); - _guessCtrl.clear(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: GuessAppBar( - controller: _guessCtrl, - onCheck: _onCheck, - ), - body: Stack( - children: [ - if(_isBig!=null) - Column( - children: [ - if(_isBig!) - ResultNotice(color:Colors.redAccent,info:'大了',controller: controller,), - Spacer(), - if(!_isBig!) - ResultNotice(color:Colors.blueAccent,info:'小了',controller: controller,), - ], - ), - Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (!_guessing) - const Text( - '点击生成随机数值', - ), - Text( - _guessing ? '**' : '$_value', - style: const TextStyle( - fontSize: 68, fontWeight: FontWeight.bold), - ), - ], - ), - ), - ], - ), - floatingActionButton: FloatingActionButton( - onPressed: _guessing ? null : _generateRandomValue, - backgroundColor: _guessing ? Colors.grey : Colors.blue, - tooltip: 'Increment', - child: const Icon(Icons.generating_tokens_outlined), - ), - ); - } - - @override - // TODO: implement wantKeepAlive - bool get wantKeepAlive => true; - - -} diff --git a/lib/cases/guess/result_notice.dart b/lib/cases/guess/result_notice.dart deleted file mode 100644 index b239d69..0000000 --- a/lib/cases/guess/result_notice.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -class ResultNotice extends StatelessWidget { - final Color color; - final String info; - final AnimationController controller; - - const ResultNotice({ - Key? key, - required this.color, - required this.info, - required this.controller, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Expanded( - child: Container( - alignment: Alignment.center, - color: color, - child: AnimatedBuilder( - animation: controller, - builder: (_, child) => Text( - info, - style: TextStyle( - fontSize: 54 * (controller.value), - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ); - } -} diff --git a/lib/cases/paper/color_selector.dart b/lib/cases/paper/color_selector.dart deleted file mode 100644 index 85fa6f4..0000000 --- a/lib/cases/paper/color_selector.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorSelector extends StatelessWidget { - final List supportColors; - final ValueChanged onSelect; - final int activeIndex; - - const ColorSelector({ - Key? key, - required this.supportColors, - required this.activeIndex, - required this.onSelect, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8), - child: Wrap( - // crossAxisAlignment: CrossAxisAlignment.end, - children: List.generate( - supportColors.length, - _buildByIndex, - )), - ); - } - - Widget _buildByIndex(int index) { - bool select = index == activeIndex; - return GestureDetector( - onTap: () => onSelect(index), - child: Container( - margin: const EdgeInsets.symmetric(horizontal: 2), - padding: const EdgeInsets.all(2), - width: 24, - height: 24, - alignment: Alignment.center, - decoration: BoxDecoration( - shape: BoxShape.circle, - // borderRadius: BorderRadius.circular(8), - border: select ? Border.all(color: Colors.blue) : null - ), - child: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: supportColors[index], - ), - ), - ), - ); - } -} diff --git a/lib/cases/paper/conform_dialog.dart b/lib/cases/paper/conform_dialog.dart deleted file mode 100644 index fcfee66..0000000 --- a/lib/cases/paper/conform_dialog.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -/// create by 张风捷特烈 on 2020-04-23 -/// contact me by email 1981462002@qq.com -/// 说明: - -class ConformDialog extends StatelessWidget { - final String title; - final String msg; - final String conformText; - final VoidCallback onConform; - - ConformDialog({ - Key? key, - required this.title, - required this.msg, - required this.onConform, - this.conformText = '删除', - }) : super(key: key); - - final ButtonStyle conformStyle = ElevatedButton.styleFrom( - backgroundColor: Colors.redAccent, - foregroundColor: Colors.white, - elevation: 0, - minimumSize: const Size(70, 35), - padding: EdgeInsets.zero, - shape: const StadiumBorder(), - ); - - final ButtonStyle cancelStyle = OutlinedButton.styleFrom( - minimumSize: const Size(70, 35), - elevation: 0, - padding: EdgeInsets.zero, - shape: const StadiumBorder(), - ); - - @override - Widget build(BuildContext context) { - return Dialog( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - _buildTitle(), - _buildMessage(), - _buildButtons(context), - ], - ), - ), - ); - } - - Widget _buildTitle()=>Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.warning_amber_rounded, color: Colors.orange), - const SizedBox( - width: 10, - ), - Text( - title, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold), - ), - ], - ); - - Widget _buildMessage()=>Padding( - padding: const EdgeInsets.only( - top: 15, - bottom: 15, - ), - child: Text( - msg, - style: const TextStyle(fontSize: 14), - ), - ); - - Widget _buildButtons(BuildContext context) => Row( - children: [ - const Spacer(), - OutlinedButton( - onPressed: Navigator.of(context).pop, - style: cancelStyle, - child: const Text( - '取消', - style: TextStyle(fontSize: 12, color: Colors.grey), - )), - const SizedBox(width: 10), - ElevatedButton( - onPressed: onConform, - style: conformStyle, - child: Text(conformText), - ), - ], - ); -} diff --git a/lib/cases/paper/model.dart b/lib/cases/paper/model.dart deleted file mode 100644 index f65bbca..0000000 --- a/lib/cases/paper/model.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class Line { - List points; - Color color; - double strokeWidth; - - Line({ - required this.points, - this.color = Colors.black, - this.strokeWidth = 1, - }); - -} \ No newline at end of file diff --git a/lib/cases/paper/paper.dart b/lib/cases/paper/paper.dart deleted file mode 100644 index 6c2d533..0000000 --- a/lib/cases/paper/paper.dart +++ /dev/null @@ -1,194 +0,0 @@ -import 'dart:math'; -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'color_selector.dart'; -import 'conform_dialog.dart'; - -import 'model.dart'; -import 'paper_app_bar.dart'; -import 'stork_width_selector.dart'; - -class Paper extends StatefulWidget { - const Paper({Key? key}) : super(key: key); - - @override - State createState() => _PaperState(); -} - -class _PaperState extends State with AutomaticKeepAliveClientMixin { - - @override - bool get wantKeepAlive => true; - - - List _lines = []; // 线列表 - - int _activeColorIndex = 0; // 颜色激活索引 - int _activeStorkWidthIndex = 0; // 线宽激活索引 - - // 支持的颜色 - final List supportColors = [ - Colors.black, - Colors.red, - Colors.orange, - Colors.yellow, - Colors.green, - Colors.blue, - Colors.indigo, - Colors.purple, - Colors.pink, - Colors.grey, - Colors.redAccent, - Colors.orangeAccent, - Colors.yellowAccent, - Colors.greenAccent, - Colors.blueAccent, - Colors.indigoAccent, - Colors.purpleAccent, - Colors.pinkAccent, - ]; - - // 支持的线粗 - final List supportStorkWidths = [1, 2, 4, 6, 8, 10]; - - List _historyLines = []; - - void _back() { - Line line = _lines.removeLast(); - _historyLines.add(line); - setState(() {}); - } - - void _revocation() { - Line line = _historyLines.removeLast(); - _lines.add(line); - setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: PaperAppBar( - onClear: _showClearDialog, - onBack: _lines.isEmpty ? null : _back, - onRevocation: _historyLines.isEmpty ? null : _revocation, - ), - body: Stack( - children: [ - GestureDetector( - onPanStart: _onPanStart, - onPanUpdate: _onPanUpdate, - child: CustomPaint( - painter: PaperPainter(lines: _lines), - child: ConstrainedBox(constraints: const BoxConstraints.expand()), - ), - ), - Positioned( - bottom: 0, - width: MediaQuery.of(context).size.width, - child: Row( - children: [ - Expanded( - child: ColorSelector( - supportColors: supportColors, - activeIndex: _activeColorIndex, - onSelect: _onSelectColor, - ), - ), - StorkWidthSelector( - supportStorkWidths: supportStorkWidths, - color: supportColors[_activeColorIndex], - activeIndex: _activeStorkWidthIndex, - onSelect: _onSelectStorkWidth, - ), - ], - ), - ), - ], - ), - ); - } - - void _showClearDialog() { - String msg = "您的当前操作会清空绘制内容,是否确定删除!"; - showDialog( - context: context, - builder: (ctx) => ConformDialog( - title: '清空提示', - conformText: '确定', - msg: msg, - onConform: _clear, - )); - } - - void _clear() { - _lines.clear(); - Navigator.of(context).pop(); - setState(() {}); - } - - void _onPanStart(DragStartDetails details) { - _lines.add(Line( - points: [details.localPosition], - strokeWidth: supportStorkWidths[_activeStorkWidthIndex], - color: supportColors[_activeColorIndex], - )); - } - - void _onPanUpdate(DragUpdateDetails details) { - Offset point = details.localPosition; - double distance = (_lines.last.points.last - point).distance; - if (distance > 5) { - _lines.last.points.add(details.localPosition); - setState(() {}); - } - } - - void _onSelectStorkWidth(int index) { - if (index != _activeStorkWidthIndex) { - setState(() { - _activeStorkWidthIndex = index; - }); - } - } - - void _onSelectColor(int index) { - if (index != _activeColorIndex) { - setState(() { - _activeColorIndex = index; - }); - } - } - -} - -class PaperPainter extends CustomPainter { - PaperPainter({ - required this.lines, - }) { - _paint = Paint() - ..style = PaintingStyle.stroke - ..strokeCap = StrokeCap.round; - } - - late Paint _paint; - final List lines; - - @override - void paint(Canvas canvas, Size size) { - for (int i = 0; i < lines.length; i++) { - drawLine(canvas, lines[i]); - } - } - - ///根据点位绘制线 - void drawLine(Canvas canvas, Line line) { - _paint.color = line.color; - _paint.strokeWidth = line.strokeWidth; - canvas.drawPoints(PointMode.polygon, line.points, _paint); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => true; -} diff --git a/lib/cases/paper/paper_app_bar.dart b/lib/cases/paper/paper_app_bar.dart deleted file mode 100644 index e7c136e..0000000 --- a/lib/cases/paper/paper_app_bar.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class PaperAppBar extends StatelessWidget implements PreferredSizeWidget { - final VoidCallback onClear; - final VoidCallback? onBack; - final VoidCallback? onRevocation; - - const PaperAppBar({ - Key? key, - required this.onClear, - this.onBack, - this.onRevocation, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return AppBar( - leading: BackUpButtons( - onBack: onBack, - onRevocation: onRevocation, - ), - leadingWidth: 100, - title: Text('画板绘制'), - actions: [ - IconButton( - splashRadius: 20, - onPressed: onClear, - icon: Icon(CupertinoIcons.delete, size: 20)) - ], - ); - } - - @override - Size get preferredSize => const Size.fromHeight(kToolbarHeight); -} - -class BackUpButtons extends StatelessWidget { - final VoidCallback? onBack; - final VoidCallback? onRevocation; - - const BackUpButtons({ - Key? key, - required this.onBack, - required this.onRevocation, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - const BoxConstraints cts = BoxConstraints(minHeight: 32, minWidth: 32); - Color backColor = onBack ==null?Colors.grey:Colors.black; - Color revocationColor = onRevocation ==null?Colors.grey:Colors.black; - return Center( - child: Wrap( - children: [ - Transform.scale( - scaleX: -1, - child: IconButton( - splashRadius: 20, - constraints: cts, - onPressed: onBack, - icon: Icon(Icons.next_plan_outlined,color: backColor), - ), - ), - IconButton( - splashRadius: 20, - onPressed: onRevocation, - constraints: cts, - icon: Icon(Icons.next_plan_outlined, color: revocationColor), - ) - ], - ), - ); - } -} diff --git a/lib/cases/paper/stork_width_selector.dart b/lib/cases/paper/stork_width_selector.dart deleted file mode 100644 index d399176..0000000 --- a/lib/cases/paper/stork_width_selector.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; - -class StorkWidthSelector extends StatelessWidget { - final List supportStorkWidths; - final ValueChanged onSelect; - final int activeIndex; - final Color color; - - const StorkWidthSelector({ - Key? key, - required this.supportStorkWidths, - required this.activeIndex, - required this.onSelect, - required this.color, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: List.generate( - supportStorkWidths.length, - _buildByIndex, - )), - ); - } - - Widget _buildByIndex(int index) { - bool select = index == activeIndex; - return GestureDetector( - onTap: () => onSelect(index), - child: Container( - margin: const EdgeInsets.symmetric(horizontal: 2), - width: 70, - height: 18, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - border: select ? Border.all(color: Colors.blue) : null), - child: Container( - width: 50, - color: color, - height: supportStorkWidths[index], - ), - ), - ); - } -} diff --git a/lib/components/components.dart b/lib/components/components.dart new file mode 100644 index 0000000..0d96f0d --- /dev/null +++ b/lib/components/components.dart @@ -0,0 +1,2 @@ +export 'toly_ui/toly_ui.dart'; +export 'windows/window_buttons.dart'; \ No newline at end of file diff --git a/lib/common/components/colors_panel.dart b/lib/components/project/colors_panel.dart similarity index 100% rename from lib/common/components/colors_panel.dart rename to lib/components/project/colors_panel.dart diff --git a/lib/14/02/components/tolyui/navigation/menu_meta.dart b/lib/components/toly_ui/navigation/menu_meta.dart similarity index 100% rename from lib/14/02/components/tolyui/navigation/menu_meta.dart rename to lib/components/toly_ui/navigation/menu_meta.dart diff --git a/lib/14/02/components/tolyui/navigation/toly_breadcrumb.dart b/lib/components/toly_ui/navigation/toly_breadcrumb.dart similarity index 100% rename from lib/14/02/components/tolyui/navigation/toly_breadcrumb.dart rename to lib/components/toly_ui/navigation/toly_breadcrumb.dart diff --git a/lib/14/02/components/tolyui/navigation/toly_navigation_rail.dart b/lib/components/toly_ui/navigation/toly_navigation_rail.dart similarity index 100% rename from lib/14/02/components/tolyui/navigation/toly_navigation_rail.dart rename to lib/components/toly_ui/navigation/toly_navigation_rail.dart diff --git a/lib/components/toly_ui/toly_ui.dart b/lib/components/toly_ui/toly_ui.dart new file mode 100644 index 0000000..5d49a81 --- /dev/null +++ b/lib/components/toly_ui/toly_ui.dart @@ -0,0 +1,4 @@ + +export 'navigation/menu_meta.dart'; +export 'navigation/toly_breadcrumb.dart'; +export 'navigation/toly_navigation_rail.dart'; \ No newline at end of file diff --git a/lib/14/02/components/windows/window_buttons.dart b/lib/components/windows/window_buttons.dart similarity index 100% rename from lib/14/02/components/windows/window_buttons.dart rename to lib/components/windows/window_buttons.dart diff --git a/lib/main.dart b/lib/main.dart index dda5554..4dd0ca8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,125 +1,26 @@ import 'package:flutter/material.dart'; +import 'package:window_manager/window_manager.dart'; + +import 'v3/app.dart'; void main() { - runApp(const MyApp()); + WidgetsFlutterBinding.ensureInitialized(); + setSize(); + runApp(const UnitApp()); } -class MyApp extends StatelessWidget { - const MyApp({super.key}); - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a blue toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - 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), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } +void setSize() async{ + await windowManager.ensureInitialized(); + WindowOptions windowOptions = const WindowOptions( + size: Size(800, 540), + center: true, + backgroundColor: Colors.transparent, + skipTaskbar: false, + titleBarStyle: TitleBarStyle.hidden, + ); + windowManager.waitUntilReadyToShow(windowOptions, () async { + await windowManager.show(); + await windowManager.focus(); + }); } diff --git a/lib/v1/app.dart b/lib/v1/app.dart new file mode 100644 index 0000000..c9460c2 --- /dev/null +++ b/lib/v1/app.dart @@ -0,0 +1 @@ +export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/13/03/app/navigation/app_router_delegate.dart b/lib/v1/app/navigation/app_router_delegate.dart similarity index 100% rename from lib/13/03/app/navigation/app_router_delegate.dart rename to lib/v1/app/navigation/app_router_delegate.dart diff --git a/lib/13/03/app/navigation/views/app_navigation_rail.dart b/lib/v1/app/navigation/views/app_navigation_rail.dart similarity index 100% rename from lib/13/03/app/navigation/views/app_navigation_rail.dart rename to lib/v1/app/navigation/views/app_navigation_rail.dart diff --git a/lib/13/03/app/unit_app.dart b/lib/v1/app/unit_app.dart similarity index 100% rename from lib/13/03/app/unit_app.dart rename to lib/v1/app/unit_app.dart diff --git a/lib/13/03/pages/color/color_page.dart b/lib/v1/pages/color/color_page.dart similarity index 75% rename from lib/13/03/pages/color/color_page.dart rename to lib/v1/pages/color/color_page.dart index 6fd4e70..b807f6f 100644 --- a/lib/13/03/pages/color/color_page.dart +++ b/lib/v1/pages/color/color_page.dart @@ -1,17 +1,5 @@ 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'))); -// } -// } - +import 'package:iroute/components/project/colors_panel.dart'; class ColorPage extends StatefulWidget { const ColorPage({super.key}); diff --git a/lib/13/03/pages/counter/counter_page.dart b/lib/v1/pages/counter/counter_page.dart similarity index 100% rename from lib/13/03/pages/counter/counter_page.dart rename to lib/v1/pages/counter/counter_page.dart diff --git a/lib/03/02/pages/empty_page.dart b/lib/v1/pages/empty/empty_page.dart similarity index 100% rename from lib/03/02/pages/empty_page.dart rename to lib/v1/pages/empty/empty_page.dart diff --git a/lib/13/03/pages/settings/settings_page.dart b/lib/v1/pages/settings/settings_page.dart similarity index 100% rename from lib/13/03/pages/settings/settings_page.dart rename to lib/v1/pages/settings/settings_page.dart diff --git a/lib/13/03/pages/user/user_page.dart b/lib/v1/pages/user/user_page.dart similarity index 100% rename from lib/13/03/pages/user/user_page.dart rename to lib/v1/pages/user/user_page.dart diff --git a/lib/13/03/transition/fade_transition_page.dart b/lib/v1/transition/fade_transition_page.dart similarity index 100% rename from lib/13/03/transition/fade_transition_page.dart rename to lib/v1/transition/fade_transition_page.dart diff --git a/lib/13/03/transition/no_transition_page.dart b/lib/v1/transition/no_transition_page.dart similarity index 100% rename from lib/13/03/transition/no_transition_page.dart rename to lib/v1/transition/no_transition_page.dart diff --git a/lib/v2/app.dart b/lib/v2/app.dart new file mode 100644 index 0000000..c9460c2 --- /dev/null +++ b/lib/v2/app.dart @@ -0,0 +1 @@ +export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/14/01/app/navigation/app_router_delegate.dart b/lib/v2/app/navigation/app_router_delegate.dart similarity index 85% rename from lib/14/01/app/navigation/app_router_delegate.dart rename to lib/v2/app/navigation/app_router_delegate.dart index 587f207..80d87d0 100644 --- a/lib/14/01/app/navigation/app_router_delegate.dart +++ b/lib/v2/app/navigation/app_router_delegate.dart @@ -2,9 +2,8 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:iroute/13/04/app/navigation/router/iroute.dart'; -import 'package:iroute/common/pages/stl_color_page.dart'; +import '../../pages/color/color_detail_page.dart'; import '../../pages/color/color_page.dart'; import '../../pages/empty/empty_page.dart'; import '../../pages/settings/settings_page.dart'; @@ -52,28 +51,6 @@ class AppRouterDelegate extends RouterDelegate with ChangeNotifier { notifyListeners(); } - // IRoute? parserPath(String path){ - // - // List parts = path.split('/'); - // String lever1 = '/${parts[1]}'; - // List iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList(); - // - // int counter = 2; - // - // IRoute? result; - // String check = lever1; - // for(int i = 0;i with ChangeNotifier { Color color = Color(int.parse(selectedColor, radix: 16)); result.add( FadeTransitionPage( key: const ValueKey('/color/detail'), - child:StlColorPage(color: color), + child:ColorDetailPage(color: color), )); } } diff --git a/lib/13/04/app/navigation/router/iroute.dart b/lib/v2/app/navigation/router/iroute.dart similarity index 100% rename from lib/13/04/app/navigation/router/iroute.dart rename to lib/v2/app/navigation/router/iroute.dart diff --git a/lib/13/04/app/navigation/views/app_navigation_rail.dart b/lib/v2/app/navigation/views/app_navigation_rail.dart similarity index 100% rename from lib/13/04/app/navigation/views/app_navigation_rail.dart rename to lib/v2/app/navigation/views/app_navigation_rail.dart diff --git a/lib/13/04/app/unit_app.dart b/lib/v2/app/unit_app.dart similarity index 100% rename from lib/13/04/app/unit_app.dart rename to lib/v2/app/unit_app.dart diff --git a/lib/13/04/pages/color/color_add_page.dart b/lib/v2/pages/color/color_add_page.dart similarity index 100% rename from lib/13/04/pages/color/color_add_page.dart rename to lib/v2/pages/color/color_add_page.dart diff --git a/lib/common/pages/stl_color_page.dart b/lib/v2/pages/color/color_detail_page.dart similarity index 89% rename from lib/common/pages/stl_color_page.dart rename to lib/v2/pages/color/color_detail_page.dart index 134b5ed..2f9c93e 100644 --- a/lib/common/pages/stl_color_page.dart +++ b/lib/v2/pages/color/color_detail_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -class StlColorPage extends StatelessWidget { +class ColorDetailPage extends StatelessWidget { final Color color; - const StlColorPage({super.key, required this.color}); + const ColorDetailPage({super.key, required this.color}); @override Widget build(BuildContext context) { diff --git a/lib/13/04/pages/color/color_page.dart b/lib/v2/pages/color/color_page.dart similarity index 95% rename from lib/13/04/pages/color/color_page.dart rename to lib/v2/pages/color/color_page.dart index 9c8ca6d..1419c09 100644 --- a/lib/13/04/pages/color/color_page.dart +++ b/lib/v2/pages/color/color_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:iroute/common/components/colors_panel.dart'; +import 'package:iroute/components/project/colors_panel.dart'; import '../../app/navigation/app_router_delegate.dart'; class ColorPage extends StatefulWidget { diff --git a/lib/13/04/pages/counter/counter_page.dart b/lib/v2/pages/counter/counter_page.dart similarity index 100% rename from lib/13/04/pages/counter/counter_page.dart rename to lib/v2/pages/counter/counter_page.dart diff --git a/lib/03/03/pages/empty_page.dart b/lib/v2/pages/empty/empty_page.dart similarity index 100% rename from lib/03/03/pages/empty_page.dart rename to lib/v2/pages/empty/empty_page.dart diff --git a/lib/13/04/pages/settings/settings_page.dart b/lib/v2/pages/settings/settings_page.dart similarity index 100% rename from lib/13/04/pages/settings/settings_page.dart rename to lib/v2/pages/settings/settings_page.dart diff --git a/lib/13/04/pages/user/user_page.dart b/lib/v2/pages/user/user_page.dart similarity index 100% rename from lib/13/04/pages/user/user_page.dart rename to lib/v2/pages/user/user_page.dart diff --git a/lib/13/04/transition/fade_transition_page.dart b/lib/v2/transition/fade_transition_page.dart similarity index 100% rename from lib/13/04/transition/fade_transition_page.dart rename to lib/v2/transition/fade_transition_page.dart diff --git a/lib/13/04/transition/no_transition_page.dart b/lib/v2/transition/no_transition_page.dart similarity index 100% rename from lib/13/04/transition/no_transition_page.dart rename to lib/v2/transition/no_transition_page.dart diff --git a/lib/v3/app.dart b/lib/v3/app.dart new file mode 100644 index 0000000..c9460c2 --- /dev/null +++ b/lib/v3/app.dart @@ -0,0 +1 @@ +export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/14/02/app/navigation/router/app_router_delegate.dart b/lib/v3/app/navigation/router/app_router_delegate.dart similarity index 96% rename from lib/14/02/app/navigation/router/app_router_delegate.dart rename to lib/v3/app/navigation/router/app_router_delegate.dart index 1026168..f5a8fde 100644 --- a/lib/14/02/app/navigation/router/app_router_delegate.dart +++ b/lib/v3/app/navigation/router/app_router_delegate.dart @@ -2,8 +2,6 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:iroute/13/04/app/navigation/router/iroute.dart'; -import 'package:iroute/common/pages/stl_color_page.dart'; import '../../../pages/color/color_detail_page.dart'; import '../../../pages/color/color_page.dart'; @@ -11,7 +9,6 @@ import '../../../pages/empty/empty_page.dart'; import '../../../pages/settings/settings_page.dart'; import '../../../pages/counter/counter_page.dart'; import '../../../pages/sort/sort_page.dart'; -import '../../../pages/user/user_page.dart'; import '../../../transition/fade_transition_page.dart'; import '../../../pages/color/color_add_page.dart'; diff --git a/lib/14/01/app/navigation/router/iroute.dart b/lib/v3/app/navigation/router/iroute.dart similarity index 100% rename from lib/14/01/app/navigation/router/iroute.dart rename to lib/v3/app/navigation/router/iroute.dart diff --git a/lib/14/02/app/navigation/views/app_navigation.dart b/lib/v3/app/navigation/views/app_navigation.dart similarity index 100% rename from lib/14/02/app/navigation/views/app_navigation.dart rename to lib/v3/app/navigation/views/app_navigation.dart diff --git a/lib/14/02/app/navigation/views/app_navigation_rail.dart b/lib/v3/app/navigation/views/app_navigation_rail.dart similarity index 95% rename from lib/14/02/app/navigation/views/app_navigation_rail.dart rename to lib/v3/app/navigation/views/app_navigation_rail.dart index 27d3d8d..f6a44b4 100644 --- a/lib/14/02/app/navigation/views/app_navigation_rail.dart +++ b/lib/v3/app/navigation/views/app_navigation_rail.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import '../../../components/tolyui/navigation/toly_navigation_rail.dart'; +import 'package:iroute/components/toly_ui/toly_ui.dart'; import '../router/app_router_delegate.dart'; class AppNavigationRail extends StatefulWidget { diff --git a/lib/14/02/app/navigation/views/background.dart b/lib/v3/app/navigation/views/background.dart similarity index 100% rename from lib/14/02/app/navigation/views/background.dart rename to lib/v3/app/navigation/views/background.dart diff --git a/lib/14/02/app/navigation/views/top_bar.dart b/lib/v3/app/navigation/views/top_bar.dart similarity index 94% rename from lib/14/02/app/navigation/views/top_bar.dart rename to lib/v3/app/navigation/views/top_bar.dart index 24a8c35..0e536ba 100644 --- a/lib/14/02/app/navigation/views/top_bar.dart +++ b/lib/v3/app/navigation/views/top_bar.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:iroute/components/components.dart'; import '../router/app_router_delegate.dart'; import 'package:window_manager/window_manager.dart'; -import '../../../components/tolyui/navigation/toly_breadcrumb.dart'; -import '../../../components/windows/window_buttons.dart'; class TopBar extends StatelessWidget { const TopBar({super.key}); diff --git a/lib/14/02/app/unit_app.dart b/lib/v3/app/unit_app.dart similarity index 100% rename from lib/14/02/app/unit_app.dart rename to lib/v3/app/unit_app.dart diff --git a/lib/14/02/pages/color/color_add_page.dart b/lib/v3/pages/color/color_add_page.dart similarity index 100% rename from lib/14/02/pages/color/color_add_page.dart rename to lib/v3/pages/color/color_add_page.dart diff --git a/lib/14/02/pages/color/color_detail_page.dart b/lib/v3/pages/color/color_detail_page.dart similarity index 100% rename from lib/14/02/pages/color/color_detail_page.dart rename to lib/v3/pages/color/color_detail_page.dart diff --git a/lib/14/02/pages/color/color_page.dart b/lib/v3/pages/color/color_page.dart similarity index 95% rename from lib/14/02/pages/color/color_page.dart rename to lib/v3/pages/color/color_page.dart index 4c526d0..213165b 100644 --- a/lib/14/02/pages/color/color_page.dart +++ b/lib/v3/pages/color/color_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:iroute/common/components/colors_panel.dart'; +import 'package:iroute/components/project/colors_panel.dart'; import '../../app/navigation/router/app_router_delegate.dart'; class ColorPage extends StatefulWidget { diff --git a/lib/14/01/pages/counter/counter_page.dart b/lib/v3/pages/counter/counter_page.dart similarity index 100% rename from lib/14/01/pages/counter/counter_page.dart rename to lib/v3/pages/counter/counter_page.dart diff --git a/lib/13/03/pages/empty/empty_page.dart b/lib/v3/pages/empty/empty_page.dart similarity index 100% rename from lib/13/03/pages/empty/empty_page.dart rename to lib/v3/pages/empty/empty_page.dart diff --git a/lib/14/01/pages/settings/settings_page.dart b/lib/v3/pages/settings/settings_page.dart similarity index 100% rename from lib/14/01/pages/settings/settings_page.dart rename to lib/v3/pages/settings/settings_page.dart diff --git a/lib/14/02/pages/sort/sort_page.dart b/lib/v3/pages/sort/sort_page.dart similarity index 100% rename from lib/14/02/pages/sort/sort_page.dart rename to lib/v3/pages/sort/sort_page.dart diff --git a/lib/14/01/pages/user/user_page.dart b/lib/v3/pages/user/user_page.dart similarity index 100% rename from lib/14/01/pages/user/user_page.dart rename to lib/v3/pages/user/user_page.dart diff --git a/lib/13/go/raw_book/src/widgets/fade_transition_page.dart b/lib/v3/transition/fade_transition_page.dart similarity index 100% rename from lib/13/go/raw_book/src/widgets/fade_transition_page.dart rename to lib/v3/transition/fade_transition_page.dart diff --git a/lib/14/01/transition/no_transition_page.dart b/lib/v3/transition/no_transition_page.dart similarity index 100% rename from lib/14/01/transition/no_transition_page.dart rename to lib/v3/transition/no_transition_page.dart diff --git a/test/parser/main.dart b/test/parser/main.dart index 403d9a6..e5cda3d 100644 --- a/test/parser/main.dart +++ b/test/parser/main.dart @@ -1,46 +1,46 @@ -import 'package:iroute/13/04/app/navigation/router/iroute.dart'; - -void main() { - String path = '/color/detail/a'; - // List parts = path.split('/'); - // print(parts); - // print(parserPath(path)); - - Uri uri = Uri.parse(path); - print(uri.fragment); - print(uri.pathSegments); - - List parts = uri.pathSegments; - - parts = List.of(parts)..removeLast(); - String result = parts.join('/'); - print(result); -} - - -IRoute? parserPath(String path){ - - List parts = path.split('/'); - String lever1 = '/${parts[1]}'; - List iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList(); - - int counter = 2; - - IRoute? result; - String check = lever1; - List children = iRoutes.first.children; - - check = check +"/" + parts[counter]; - - for(int i = 0;i parts = path.split('/'); +// // print(parts); +// // print(parserPath(path)); +// +// Uri uri = Uri.parse(path); +// print(uri.fragment); +// print(uri.pathSegments); +// +// List parts = uri.pathSegments; +// +// parts = List.of(parts)..removeLast(); +// String result = parts.join('/'); +// print(result); +// } +// +// +// IRoute? parserPath(String path){ +// +// List parts = path.split('/'); +// String lever1 = '/${parts[1]}'; +// List iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList(); +// +// int counter = 2; +// +// IRoute? result; +// String check = lever1; +// List children = iRoutes.first.children; +// +// check = check +"/" + parts[counter]; +// +// for(int i = 0;i