From 1aeab4fa6429e003f44cb1920a44e8f9bc325bce Mon Sep 17 00:00:00 2001 From: toly <1981462002@qq.com> Date: Wed, 27 Dec 2023 00:55:04 +0800 Subject: [PATCH] 1 --- lib/07/节点介绍.txt | 4 +- lib/09/节点介绍.txt | 4 + lib/10/节点介绍.txt | 5 + lib/11/节点介绍.txt | 1 + lib/12/01/main.dart | 11 - lib/13/01_/main.dart | 15 - lib/13/01_/pages/app.dart | 50 -- lib/13/01_/pages/color_add_page.dart | 67 --- lib/13/01_/pages/home_page.dart | 46 -- lib/13/01_/route/parsed_route.dart | 27 - lib/13/01_/route/parser.dart | 135 ----- lib/13/01_/route/route_state.dart | 48 -- lib/13/01__/main.dart | 15 - lib/13/01__/pages/app.dart | 46 -- lib/13/01__/pages/color_add_page.dart | 67 --- lib/13/01__/pages/home_page.dart | 46 -- lib/13/01__/route/parsed_route.dart | 21 - lib/13/01__/route/parser.dart | 119 ----- lib/13/01__/route/route_state.dart | 48 -- lib/13/01___/main.dart | 15 - lib/13/01___/pages/app.dart | 36 -- lib/13/01___/pages/color_add_page.dart | 67 --- lib/13/01___/pages/home_page.dart | 47 -- lib/13/01___/route/parsed_route.dart | 21 - lib/13/01___/route/parser.dart | 122 ----- lib/13/01___/route/route_state.dart | 48 -- lib/13/01____/main.dart | 14 - lib/13/01____/pages/app/app.dart | 29 -- .../01____/pages/app/app_router_delegate.dart | 73 --- lib/13/01____/pages/app/app_tool_bar.dart | 64 --- lib/13/01____/pages/home_page.dart | 30 -- lib/13/01____/pages/page_a.dart | 30 -- lib/13/01____/pages/page_b.dart | 32 -- lib/13/01____/pages/page_c.dart | 24 - lib/13/02_/main.dart | 13 - lib/13/02_/menus.dart | 83 ---- lib/13/02_/pages/app/app.dart | 107 ---- lib/13/02_/pages/app/root_content.dart | 140 ------ lib/13/02_/pages/color_page.dart | 11 - lib/13/02_/transition/fade_transition.dart | 58 --- lib/13/02__/main.dart | 15 - lib/13/02__/pages/app.dart | 56 --- lib/13/02__/pages/color_add_page.dart | 67 --- lib/13/02__/pages/home_page.dart | 43 -- lib/13/02__/route/parsed_route.dart | 49 -- lib/13/02__/route/parser.dart | 153 ------ lib/13/02__/route/route_state.dart | 48 -- lib/13/02__/store/app_state.dart | 32 -- lib/13/03_/main.dart | 13 - lib/13/03_/menus.dart | 76 --- lib/13/03_/pages/app/app.dart | 89 ---- lib/13/03_/pages/app/root_content.dart | 43 -- lib/13/go/async_redirection.dart | 244 ---------- lib/13/go/books/main.dart | 171 ------- lib/13/go/books/src/auth.dart | 46 -- lib/13/go/books/src/data.dart | 7 - lib/13/go/books/src/data/author.dart | 23 - lib/13/go/books/src/data/book.dart | 32 -- lib/13/go/books/src/data/library.dart | 76 --- .../go/books/src/screens/author_details.dart | 49 -- lib/13/go/books/src/screens/authors.dart | 31 -- lib/13/go/books/src/screens/book_details.dart | 77 --- lib/13/go/books/src/screens/books.dart | 118 ----- lib/13/go/books/src/screens/scaffold.dart | 71 --- lib/13/go/books/src/screens/settings.dart | 101 ---- lib/13/go/books/src/screens/sign_in.dart | 77 --- lib/13/go/books/src/widgets/author_list.dart | 37 -- lib/13/go/books/src/widgets/book_list.dart | 37 -- lib/13/go/exception_handling.dart | 87 ---- lib/13/go/main.dart | 87 ---- lib/13/go/named_routes.dart | 181 ------- .../others/custom_stateful_shell_route.dart | 460 ------------------ lib/13/go/others/error_screen.dart | 110 ----- lib/13/go/others/extra_param.dart | 133 ----- lib/13/go/others/init_loc.dart | 110 ----- lib/13/go/others/nav_observer.dart | 167 ------- lib/13/go/others/push.dart | 101 ---- lib/13/go/others/router_neglect.dart | 95 ---- lib/13/go/others/state_restoration.dart | 102 ---- .../stateful_shell_state_restoration.dart | 236 --------- lib/13/go/others/transitions.dart | 163 ------- lib/13/go/path_and_query_parameters.dart | 169 ------- lib/13/go/raw_book/main.dart | 27 - lib/13/go/raw_book/src/app.dart | 81 --- lib/13/go/raw_book/src/auth.dart | 47 -- lib/13/go/raw_book/src/data.dart | 7 - lib/13/go/raw_book/src/data/author.dart | 13 - lib/13/go/raw_book/src/data/book.dart | 15 - lib/13/go/raw_book/src/data/library.dart | 61 --- lib/13/go/raw_book/src/routing.dart | 8 - lib/13/go/raw_book/src/routing/delegate.dart | 47 -- .../go/raw_book/src/routing/parsed_route.dart | 51 -- lib/13/go/raw_book/src/routing/parser.dart | 62 --- .../go/raw_book/src/routing/route_state.dart | 48 -- .../raw_book/src/screens/author_details.dart | 39 -- lib/13/go/raw_book/src/screens/authors.dart | 28 -- .../go/raw_book/src/screens/book_details.dart | 66 --- lib/13/go/raw_book/src/screens/books.dart | 111 ----- lib/13/go/raw_book/src/screens/navigator.dart | 108 ---- lib/13/go/raw_book/src/screens/scaffold.dart | 54 -- .../raw_book/src/screens/scaffold_body.dart | 63 --- lib/13/go/raw_book/src/screens/settings.dart | 95 ---- lib/13/go/raw_book/src/screens/sign_in.dart | 69 --- .../go/raw_book/src/widgets/author_list.dart | 32 -- lib/13/go/raw_book/src/widgets/book_list.dart | 32 -- lib/13/go/redirection.dart | 146 ------ lib/13/go/shell_route.dart | 289 ----------- lib/13/go/stateful_shell_route.dart | 324 ------------ lib/13/go/transition_animations.dart | 175 ------- lib/13/go_color/main.dart | 13 - lib/13/go_color/pages/app.dart | 50 -- lib/13/go_color/pages/color_add_page.dart | 67 --- lib/13/go_color/pages/home_page.dart | 61 --- lib/13/go_color/route/parsed_route.dart | 21 - lib/13/go_color/route/parser.dart | 112 ----- lib/13/go_color/route/route_state.dart | 48 -- lib/14/01/main.dart | 9 +- lib/{12 => 14}/01/pages/app/app.dart | 0 .../01/pages/app/app_navigation.dart | 0 lib/{12 => 14}/01/pages/app/app_tool_bar.dart | 0 lib/{12 => 14}/01/pages/home_page.dart | 0 lib/{12 => 14}/01/pages/page_a.dart | 0 lib/{12 => 14}/01/pages/page_b.dart | 0 lib/{12 => 14}/01/pages/page_c.dart | 0 .../01/transition/fade_transition_page.dart | 53 -- lib/14/节点介绍.txt | 1 + lib/{13 => 15}/01/main.dart | 0 lib/{13 => 15}/01/pages/app/app.dart | 0 .../01/pages/app/app_router_delegate.dart | 0 lib/{13 => 15}/01/pages/app/app_tool_bar.dart | 0 lib/{13 => 15}/01/pages/home_page.dart | 0 lib/{13 => 15}/01/pages/page_a.dart | 0 lib/{13 => 15}/01/pages/page_b.dart | 0 lib/{13 => 15}/01/pages/page_c.dart | 0 lib/{13 => 15}/02/main.dart | 0 lib/{13 => 15}/02/pages/app/app.dart | 0 .../02/pages/app/app_router_delegate.dart | 0 lib/{13 => 15}/02/pages/app/app_tool_bar.dart | 0 lib/{13 => 15}/02/pages/home_page.dart | 0 lib/{13 => 15}/02/pages/page_a.dart | 0 lib/{13 => 15}/02/pages/page_b.dart | 0 lib/{13 => 15}/02/pages/page_c.dart | 0 .../app/navigation/app_router_delegate.dart | 0 .../navigation/views/app_navigation_rail.dart | 0 lib/{13 => 15}/03/app/unit_app.dart | 0 lib/{13 => 15}/03/main.dart | 0 lib/{13 => 15}/03/pages/color/color_page.dart | 0 .../03/pages/counter/counter_page.dart | 0 lib/{13 => 15}/03/pages/empty/empty_page.dart | 0 .../03/pages/settings/settings_page.dart | 0 lib/{13 => 15}/03/pages/user/user_page.dart | 0 .../03/transition/fade_transition_page.dart | 0 .../03/transition/no_transition_page.dart | 0 .../app/navigation/app_router_delegate.dart | 1 - .../04/app/navigation/router/iroute.dart | 0 .../navigation/views/app_navigation_rail.dart | 0 lib/{13 => 15}/04/app/unit_app.dart | 0 lib/{13 => 15}/04/main.dart | 0 .../04/pages/color/color_add_page.dart | 0 lib/{13 => 15}/04/pages/color/color_page.dart | 0 .../04/pages/counter/counter_page.dart | 0 lib/{13 => 15}/04/pages/empty/empty_page.dart | 0 .../04/pages/settings/settings_page.dart | 0 lib/{13 => 15}/04/pages/user/user_page.dart | 0 .../04/transition/fade_transition_page.dart | 0 .../04/transition/no_transition_page.dart | 0 lib/{13 => 15}/节点介绍.txt | 0 .../app/navigation/app_router_delegate.dart | 1 - .../01/app/navigation/router/iroute.dart | 0 .../navigation/views/app_navigation_rail.dart | 0 lib/{14 => 16}/01/app/unit_app.dart | 0 lib/16/01/main.dart | 16 + .../01/pages/color/color_add_page.dart | 0 lib/{14 => 16}/01/pages/color/color_page.dart | 0 .../01/pages/counter/counter_page.dart | 0 lib/{14 => 16}/01/pages/empty/empty_page.dart | 0 .../01/pages/settings/settings_page.dart | 0 lib/{14 => 16}/01/pages/user/user_page.dart | 0 .../01/transition}/fade_transition_page.dart | 0 .../01/transition/no_transition_page.dart | 0 linux/flutter/generated_plugin_registrant.cc | 4 - linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - pubspec.lock | 192 +------- pubspec.yaml | 9 - test/parser/main.dart | 70 +-- windows/flutter/CMakeLists.txt | 7 +- .../flutter/generated_plugin_registrant.cc | 3 - windows/flutter/generated_plugins.cmake | 1 - 189 files changed, 85 insertions(+), 8676 deletions(-) create mode 100644 lib/09/节点介绍.txt create mode 100644 lib/10/节点介绍.txt create mode 100644 lib/11/节点介绍.txt delete mode 100644 lib/12/01/main.dart delete mode 100644 lib/13/01_/main.dart delete mode 100644 lib/13/01_/pages/app.dart delete mode 100644 lib/13/01_/pages/color_add_page.dart delete mode 100644 lib/13/01_/pages/home_page.dart delete mode 100644 lib/13/01_/route/parsed_route.dart delete mode 100644 lib/13/01_/route/parser.dart delete mode 100644 lib/13/01_/route/route_state.dart delete mode 100644 lib/13/01__/main.dart delete mode 100644 lib/13/01__/pages/app.dart delete mode 100644 lib/13/01__/pages/color_add_page.dart delete mode 100644 lib/13/01__/pages/home_page.dart delete mode 100644 lib/13/01__/route/parsed_route.dart delete mode 100644 lib/13/01__/route/parser.dart delete mode 100644 lib/13/01__/route/route_state.dart delete mode 100644 lib/13/01___/main.dart delete mode 100644 lib/13/01___/pages/app.dart delete mode 100644 lib/13/01___/pages/color_add_page.dart delete mode 100644 lib/13/01___/pages/home_page.dart delete mode 100644 lib/13/01___/route/parsed_route.dart delete mode 100644 lib/13/01___/route/parser.dart delete mode 100644 lib/13/01___/route/route_state.dart delete mode 100644 lib/13/01____/main.dart delete mode 100644 lib/13/01____/pages/app/app.dart delete mode 100644 lib/13/01____/pages/app/app_router_delegate.dart delete mode 100644 lib/13/01____/pages/app/app_tool_bar.dart delete mode 100644 lib/13/01____/pages/home_page.dart delete mode 100644 lib/13/01____/pages/page_a.dart delete mode 100644 lib/13/01____/pages/page_b.dart delete mode 100644 lib/13/01____/pages/page_c.dart delete mode 100644 lib/13/02_/main.dart delete mode 100644 lib/13/02_/menus.dart delete mode 100644 lib/13/02_/pages/app/app.dart delete mode 100644 lib/13/02_/pages/app/root_content.dart delete mode 100644 lib/13/02_/pages/color_page.dart delete mode 100644 lib/13/02_/transition/fade_transition.dart delete mode 100644 lib/13/02__/main.dart delete mode 100644 lib/13/02__/pages/app.dart delete mode 100644 lib/13/02__/pages/color_add_page.dart delete mode 100644 lib/13/02__/pages/home_page.dart delete mode 100644 lib/13/02__/route/parsed_route.dart delete mode 100644 lib/13/02__/route/parser.dart delete mode 100644 lib/13/02__/route/route_state.dart delete mode 100644 lib/13/02__/store/app_state.dart delete mode 100644 lib/13/03_/main.dart delete mode 100644 lib/13/03_/menus.dart delete mode 100644 lib/13/03_/pages/app/app.dart delete mode 100644 lib/13/03_/pages/app/root_content.dart delete mode 100644 lib/13/go/async_redirection.dart delete mode 100644 lib/13/go/books/main.dart delete mode 100644 lib/13/go/books/src/auth.dart delete mode 100644 lib/13/go/books/src/data.dart delete mode 100644 lib/13/go/books/src/data/author.dart delete mode 100644 lib/13/go/books/src/data/book.dart delete mode 100644 lib/13/go/books/src/data/library.dart delete mode 100644 lib/13/go/books/src/screens/author_details.dart delete mode 100644 lib/13/go/books/src/screens/authors.dart delete mode 100644 lib/13/go/books/src/screens/book_details.dart delete mode 100644 lib/13/go/books/src/screens/books.dart delete mode 100644 lib/13/go/books/src/screens/scaffold.dart delete mode 100644 lib/13/go/books/src/screens/settings.dart delete mode 100644 lib/13/go/books/src/screens/sign_in.dart delete mode 100644 lib/13/go/books/src/widgets/author_list.dart delete mode 100644 lib/13/go/books/src/widgets/book_list.dart delete mode 100644 lib/13/go/exception_handling.dart delete mode 100644 lib/13/go/main.dart delete mode 100644 lib/13/go/named_routes.dart delete mode 100644 lib/13/go/others/custom_stateful_shell_route.dart delete mode 100644 lib/13/go/others/error_screen.dart delete mode 100644 lib/13/go/others/extra_param.dart delete mode 100644 lib/13/go/others/init_loc.dart delete mode 100644 lib/13/go/others/nav_observer.dart delete mode 100644 lib/13/go/others/push.dart delete mode 100644 lib/13/go/others/router_neglect.dart delete mode 100644 lib/13/go/others/state_restoration.dart delete mode 100644 lib/13/go/others/stateful_shell_state_restoration.dart delete mode 100644 lib/13/go/others/transitions.dart delete mode 100644 lib/13/go/path_and_query_parameters.dart delete mode 100644 lib/13/go/raw_book/main.dart delete mode 100644 lib/13/go/raw_book/src/app.dart delete mode 100644 lib/13/go/raw_book/src/auth.dart delete mode 100644 lib/13/go/raw_book/src/data.dart delete mode 100644 lib/13/go/raw_book/src/data/author.dart delete mode 100644 lib/13/go/raw_book/src/data/book.dart delete mode 100644 lib/13/go/raw_book/src/data/library.dart delete mode 100644 lib/13/go/raw_book/src/routing.dart delete mode 100644 lib/13/go/raw_book/src/routing/delegate.dart delete mode 100644 lib/13/go/raw_book/src/routing/parsed_route.dart delete mode 100644 lib/13/go/raw_book/src/routing/parser.dart delete mode 100644 lib/13/go/raw_book/src/routing/route_state.dart delete mode 100644 lib/13/go/raw_book/src/screens/author_details.dart delete mode 100644 lib/13/go/raw_book/src/screens/authors.dart delete mode 100644 lib/13/go/raw_book/src/screens/book_details.dart delete mode 100644 lib/13/go/raw_book/src/screens/books.dart delete mode 100644 lib/13/go/raw_book/src/screens/navigator.dart delete mode 100644 lib/13/go/raw_book/src/screens/scaffold.dart delete mode 100644 lib/13/go/raw_book/src/screens/scaffold_body.dart delete mode 100644 lib/13/go/raw_book/src/screens/settings.dart delete mode 100644 lib/13/go/raw_book/src/screens/sign_in.dart delete mode 100644 lib/13/go/raw_book/src/widgets/author_list.dart delete mode 100644 lib/13/go/raw_book/src/widgets/book_list.dart delete mode 100644 lib/13/go/redirection.dart delete mode 100644 lib/13/go/shell_route.dart delete mode 100644 lib/13/go/stateful_shell_route.dart delete mode 100644 lib/13/go/transition_animations.dart delete mode 100644 lib/13/go_color/main.dart delete mode 100644 lib/13/go_color/pages/app.dart delete mode 100644 lib/13/go_color/pages/color_add_page.dart delete mode 100644 lib/13/go_color/pages/home_page.dart delete mode 100644 lib/13/go_color/route/parsed_route.dart delete mode 100644 lib/13/go_color/route/parser.dart delete mode 100644 lib/13/go_color/route/route_state.dart rename lib/{12 => 14}/01/pages/app/app.dart (100%) rename lib/{12 => 14}/01/pages/app/app_navigation.dart (100%) rename lib/{12 => 14}/01/pages/app/app_tool_bar.dart (100%) rename lib/{12 => 14}/01/pages/home_page.dart (100%) rename lib/{12 => 14}/01/pages/page_a.dart (100%) rename lib/{12 => 14}/01/pages/page_b.dart (100%) rename lib/{12 => 14}/01/pages/page_c.dart (100%) delete mode 100644 lib/14/01/transition/fade_transition_page.dart create mode 100644 lib/14/节点介绍.txt rename lib/{13 => 15}/01/main.dart (100%) rename lib/{13 => 15}/01/pages/app/app.dart (100%) rename lib/{13 => 15}/01/pages/app/app_router_delegate.dart (100%) rename lib/{13 => 15}/01/pages/app/app_tool_bar.dart (100%) rename lib/{13 => 15}/01/pages/home_page.dart (100%) rename lib/{13 => 15}/01/pages/page_a.dart (100%) rename lib/{13 => 15}/01/pages/page_b.dart (100%) rename lib/{13 => 15}/01/pages/page_c.dart (100%) rename lib/{13 => 15}/02/main.dart (100%) rename lib/{13 => 15}/02/pages/app/app.dart (100%) rename lib/{13 => 15}/02/pages/app/app_router_delegate.dart (100%) rename lib/{13 => 15}/02/pages/app/app_tool_bar.dart (100%) rename lib/{13 => 15}/02/pages/home_page.dart (100%) rename lib/{13 => 15}/02/pages/page_a.dart (100%) rename lib/{13 => 15}/02/pages/page_b.dart (100%) rename lib/{13 => 15}/02/pages/page_c.dart (100%) rename lib/{13 => 15}/03/app/navigation/app_router_delegate.dart (100%) rename lib/{13 => 15}/03/app/navigation/views/app_navigation_rail.dart (100%) rename lib/{13 => 15}/03/app/unit_app.dart (100%) rename lib/{13 => 15}/03/main.dart (100%) rename lib/{13 => 15}/03/pages/color/color_page.dart (100%) rename lib/{13 => 15}/03/pages/counter/counter_page.dart (100%) rename lib/{13 => 15}/03/pages/empty/empty_page.dart (100%) rename lib/{13 => 15}/03/pages/settings/settings_page.dart (100%) rename lib/{13 => 15}/03/pages/user/user_page.dart (100%) rename lib/{13 => 15}/03/transition/fade_transition_page.dart (100%) rename lib/{13 => 15}/03/transition/no_transition_page.dart (100%) rename lib/{14/01 => 15/04}/app/navigation/app_router_delegate.dart (98%) rename lib/{13 => 15}/04/app/navigation/router/iroute.dart (100%) rename lib/{13 => 15}/04/app/navigation/views/app_navigation_rail.dart (100%) rename lib/{13 => 15}/04/app/unit_app.dart (100%) rename lib/{13 => 15}/04/main.dart (100%) rename lib/{13 => 15}/04/pages/color/color_add_page.dart (100%) rename lib/{13 => 15}/04/pages/color/color_page.dart (100%) rename lib/{13 => 15}/04/pages/counter/counter_page.dart (100%) rename lib/{13 => 15}/04/pages/empty/empty_page.dart (100%) rename lib/{13 => 15}/04/pages/settings/settings_page.dart (100%) rename lib/{13 => 15}/04/pages/user/user_page.dart (100%) rename lib/{13 => 15}/04/transition/fade_transition_page.dart (100%) rename lib/{13 => 15}/04/transition/no_transition_page.dart (100%) rename lib/{13 => 15}/节点介绍.txt (100%) rename lib/{13/04 => 16/01}/app/navigation/app_router_delegate.dart (98%) rename lib/{14 => 16}/01/app/navigation/router/iroute.dart (100%) rename lib/{14 => 16}/01/app/navigation/views/app_navigation_rail.dart (100%) rename lib/{14 => 16}/01/app/unit_app.dart (100%) create mode 100644 lib/16/01/main.dart rename lib/{14 => 16}/01/pages/color/color_add_page.dart (100%) rename lib/{14 => 16}/01/pages/color/color_page.dart (100%) rename lib/{14 => 16}/01/pages/counter/counter_page.dart (100%) rename lib/{14 => 16}/01/pages/empty/empty_page.dart (100%) rename lib/{14 => 16}/01/pages/settings/settings_page.dart (100%) rename lib/{14 => 16}/01/pages/user/user_page.dart (100%) rename lib/{13/go/raw_book/src/widgets => 16/01/transition}/fade_transition_page.dart (100%) rename lib/{14 => 16}/01/transition/no_transition_page.dart (100%) diff --git a/lib/07/节点介绍.txt b/lib/07/节点介绍.txt index b50e9a9..005a650 100644 --- a/lib/07/节点介绍.txt +++ b/lib/07/节点介绍.txt @@ -1,4 +1,2 @@ 01: 分析 push 方法。 - A、B、C 三个界面跳转。 - -02: replace \ No newline at end of file + A、B、C 三个界面跳转。 \ No newline at end of file diff --git a/lib/09/节点介绍.txt b/lib/09/节点介绍.txt new file mode 100644 index 0000000..03f4b60 --- /dev/null +++ b/lib/09/节点介绍.txt @@ -0,0 +1,4 @@ +01: 分析 pop 方法。 + A、B、C 三个界面跳转。 + +02: 分析 popUntil 方法。 \ No newline at end of file diff --git a/lib/10/节点介绍.txt b/lib/10/节点介绍.txt new file mode 100644 index 0000000..1e927ad --- /dev/null +++ b/lib/10/节点介绍.txt @@ -0,0 +1,5 @@ +app_info.dart: 弹出对话框界面 +cupertino_context_menu_demo.dart: 弹出 CupertinoContextMenu +dropdown_button_color.dart: 弹出 DropdownButton +more_pop_icon.dart: 弹出 PopupMenuButton +search_anchor_demo.dart: 弹出 SearchAnchor diff --git a/lib/11/节点介绍.txt b/lib/11/节点介绍.txt new file mode 100644 index 0000000..7177f73 --- /dev/null +++ b/lib/11/节点介绍.txt @@ -0,0 +1 @@ +路由第二动画控制器效果演示 \ No newline at end of file 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/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 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 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/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/14/01/main.dart b/lib/14/01/main.dart index 38c9d78..0ecfe3f 100644 --- a/lib/14/01/main.dart +++ b/lib/14/01/main.dart @@ -1,14 +1,9 @@ import 'package:flutter/material.dart'; - -import 'app/unit_app.dart'; -import 'app/navigation/app_router_delegate.dart'; - - - +import 'pages/app/app.dart'; void main() { - runApp(const UnitApp()); + runApp(const App()); } diff --git a/lib/12/01/pages/app/app.dart b/lib/14/01/pages/app/app.dart similarity index 100% rename from lib/12/01/pages/app/app.dart rename to lib/14/01/pages/app/app.dart diff --git a/lib/12/01/pages/app/app_navigation.dart b/lib/14/01/pages/app/app_navigation.dart similarity index 100% rename from lib/12/01/pages/app/app_navigation.dart rename to lib/14/01/pages/app/app_navigation.dart diff --git a/lib/12/01/pages/app/app_tool_bar.dart b/lib/14/01/pages/app/app_tool_bar.dart similarity index 100% rename from lib/12/01/pages/app/app_tool_bar.dart rename to lib/14/01/pages/app/app_tool_bar.dart diff --git a/lib/12/01/pages/home_page.dart b/lib/14/01/pages/home_page.dart similarity index 100% rename from lib/12/01/pages/home_page.dart rename to lib/14/01/pages/home_page.dart diff --git a/lib/12/01/pages/page_a.dart b/lib/14/01/pages/page_a.dart similarity index 100% rename from lib/12/01/pages/page_a.dart rename to lib/14/01/pages/page_a.dart diff --git a/lib/12/01/pages/page_b.dart b/lib/14/01/pages/page_b.dart similarity index 100% rename from lib/12/01/pages/page_b.dart rename to lib/14/01/pages/page_b.dart diff --git a/lib/12/01/pages/page_c.dart b/lib/14/01/pages/page_c.dart similarity index 100% rename from lib/12/01/pages/page_c.dart rename to lib/14/01/pages/page_c.dart 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/节点介绍.txt b/lib/14/节点介绍.txt new file mode 100644 index 0000000..641fb90 --- /dev/null +++ b/lib/14/节点介绍.txt @@ -0,0 +1 @@ +01: Navigator#page 的使用测试 \ No newline at end of file diff --git a/lib/13/01/main.dart b/lib/15/01/main.dart similarity index 100% rename from lib/13/01/main.dart rename to lib/15/01/main.dart diff --git a/lib/13/01/pages/app/app.dart b/lib/15/01/pages/app/app.dart similarity index 100% rename from lib/13/01/pages/app/app.dart rename to lib/15/01/pages/app/app.dart diff --git a/lib/13/01/pages/app/app_router_delegate.dart b/lib/15/01/pages/app/app_router_delegate.dart similarity index 100% rename from lib/13/01/pages/app/app_router_delegate.dart rename to lib/15/01/pages/app/app_router_delegate.dart diff --git a/lib/13/01/pages/app/app_tool_bar.dart b/lib/15/01/pages/app/app_tool_bar.dart similarity index 100% rename from lib/13/01/pages/app/app_tool_bar.dart rename to lib/15/01/pages/app/app_tool_bar.dart diff --git a/lib/13/01/pages/home_page.dart b/lib/15/01/pages/home_page.dart similarity index 100% rename from lib/13/01/pages/home_page.dart rename to lib/15/01/pages/home_page.dart diff --git a/lib/13/01/pages/page_a.dart b/lib/15/01/pages/page_a.dart similarity index 100% rename from lib/13/01/pages/page_a.dart rename to lib/15/01/pages/page_a.dart diff --git a/lib/13/01/pages/page_b.dart b/lib/15/01/pages/page_b.dart similarity index 100% rename from lib/13/01/pages/page_b.dart rename to lib/15/01/pages/page_b.dart diff --git a/lib/13/01/pages/page_c.dart b/lib/15/01/pages/page_c.dart similarity index 100% rename from lib/13/01/pages/page_c.dart rename to lib/15/01/pages/page_c.dart diff --git a/lib/13/02/main.dart b/lib/15/02/main.dart similarity index 100% rename from lib/13/02/main.dart rename to lib/15/02/main.dart diff --git a/lib/13/02/pages/app/app.dart b/lib/15/02/pages/app/app.dart similarity index 100% rename from lib/13/02/pages/app/app.dart rename to lib/15/02/pages/app/app.dart diff --git a/lib/13/02/pages/app/app_router_delegate.dart b/lib/15/02/pages/app/app_router_delegate.dart similarity index 100% rename from lib/13/02/pages/app/app_router_delegate.dart rename to lib/15/02/pages/app/app_router_delegate.dart diff --git a/lib/13/02/pages/app/app_tool_bar.dart b/lib/15/02/pages/app/app_tool_bar.dart similarity index 100% rename from lib/13/02/pages/app/app_tool_bar.dart rename to lib/15/02/pages/app/app_tool_bar.dart diff --git a/lib/13/02/pages/home_page.dart b/lib/15/02/pages/home_page.dart similarity index 100% rename from lib/13/02/pages/home_page.dart rename to lib/15/02/pages/home_page.dart diff --git a/lib/13/02/pages/page_a.dart b/lib/15/02/pages/page_a.dart similarity index 100% rename from lib/13/02/pages/page_a.dart rename to lib/15/02/pages/page_a.dart diff --git a/lib/13/02/pages/page_b.dart b/lib/15/02/pages/page_b.dart similarity index 100% rename from lib/13/02/pages/page_b.dart rename to lib/15/02/pages/page_b.dart diff --git a/lib/13/02/pages/page_c.dart b/lib/15/02/pages/page_c.dart similarity index 100% rename from lib/13/02/pages/page_c.dart rename to lib/15/02/pages/page_c.dart diff --git a/lib/13/03/app/navigation/app_router_delegate.dart b/lib/15/03/app/navigation/app_router_delegate.dart similarity index 100% rename from lib/13/03/app/navigation/app_router_delegate.dart rename to lib/15/03/app/navigation/app_router_delegate.dart diff --git a/lib/13/03/app/navigation/views/app_navigation_rail.dart b/lib/15/03/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/15/03/app/navigation/views/app_navigation_rail.dart diff --git a/lib/13/03/app/unit_app.dart b/lib/15/03/app/unit_app.dart similarity index 100% rename from lib/13/03/app/unit_app.dart rename to lib/15/03/app/unit_app.dart diff --git a/lib/13/03/main.dart b/lib/15/03/main.dart similarity index 100% rename from lib/13/03/main.dart rename to lib/15/03/main.dart diff --git a/lib/13/03/pages/color/color_page.dart b/lib/15/03/pages/color/color_page.dart similarity index 100% rename from lib/13/03/pages/color/color_page.dart rename to lib/15/03/pages/color/color_page.dart diff --git a/lib/13/03/pages/counter/counter_page.dart b/lib/15/03/pages/counter/counter_page.dart similarity index 100% rename from lib/13/03/pages/counter/counter_page.dart rename to lib/15/03/pages/counter/counter_page.dart diff --git a/lib/13/03/pages/empty/empty_page.dart b/lib/15/03/pages/empty/empty_page.dart similarity index 100% rename from lib/13/03/pages/empty/empty_page.dart rename to lib/15/03/pages/empty/empty_page.dart diff --git a/lib/13/03/pages/settings/settings_page.dart b/lib/15/03/pages/settings/settings_page.dart similarity index 100% rename from lib/13/03/pages/settings/settings_page.dart rename to lib/15/03/pages/settings/settings_page.dart diff --git a/lib/13/03/pages/user/user_page.dart b/lib/15/03/pages/user/user_page.dart similarity index 100% rename from lib/13/03/pages/user/user_page.dart rename to lib/15/03/pages/user/user_page.dart diff --git a/lib/13/03/transition/fade_transition_page.dart b/lib/15/03/transition/fade_transition_page.dart similarity index 100% rename from lib/13/03/transition/fade_transition_page.dart rename to lib/15/03/transition/fade_transition_page.dart diff --git a/lib/13/03/transition/no_transition_page.dart b/lib/15/03/transition/no_transition_page.dart similarity index 100% rename from lib/13/03/transition/no_transition_page.dart rename to lib/15/03/transition/no_transition_page.dart diff --git a/lib/14/01/app/navigation/app_router_delegate.dart b/lib/15/04/app/navigation/app_router_delegate.dart similarity index 98% rename from lib/14/01/app/navigation/app_router_delegate.dart rename to lib/15/04/app/navigation/app_router_delegate.dart index 587f207..7f9d92f 100644 --- a/lib/14/01/app/navigation/app_router_delegate.dart +++ b/lib/15/04/app/navigation/app_router_delegate.dart @@ -2,7 +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_page.dart'; diff --git a/lib/13/04/app/navigation/router/iroute.dart b/lib/15/04/app/navigation/router/iroute.dart similarity index 100% rename from lib/13/04/app/navigation/router/iroute.dart rename to lib/15/04/app/navigation/router/iroute.dart diff --git a/lib/13/04/app/navigation/views/app_navigation_rail.dart b/lib/15/04/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/15/04/app/navigation/views/app_navigation_rail.dart diff --git a/lib/13/04/app/unit_app.dart b/lib/15/04/app/unit_app.dart similarity index 100% rename from lib/13/04/app/unit_app.dart rename to lib/15/04/app/unit_app.dart diff --git a/lib/13/04/main.dart b/lib/15/04/main.dart similarity index 100% rename from lib/13/04/main.dart rename to lib/15/04/main.dart diff --git a/lib/13/04/pages/color/color_add_page.dart b/lib/15/04/pages/color/color_add_page.dart similarity index 100% rename from lib/13/04/pages/color/color_add_page.dart rename to lib/15/04/pages/color/color_add_page.dart diff --git a/lib/13/04/pages/color/color_page.dart b/lib/15/04/pages/color/color_page.dart similarity index 100% rename from lib/13/04/pages/color/color_page.dart rename to lib/15/04/pages/color/color_page.dart diff --git a/lib/13/04/pages/counter/counter_page.dart b/lib/15/04/pages/counter/counter_page.dart similarity index 100% rename from lib/13/04/pages/counter/counter_page.dart rename to lib/15/04/pages/counter/counter_page.dart diff --git a/lib/13/04/pages/empty/empty_page.dart b/lib/15/04/pages/empty/empty_page.dart similarity index 100% rename from lib/13/04/pages/empty/empty_page.dart rename to lib/15/04/pages/empty/empty_page.dart diff --git a/lib/13/04/pages/settings/settings_page.dart b/lib/15/04/pages/settings/settings_page.dart similarity index 100% rename from lib/13/04/pages/settings/settings_page.dart rename to lib/15/04/pages/settings/settings_page.dart diff --git a/lib/13/04/pages/user/user_page.dart b/lib/15/04/pages/user/user_page.dart similarity index 100% rename from lib/13/04/pages/user/user_page.dart rename to lib/15/04/pages/user/user_page.dart diff --git a/lib/13/04/transition/fade_transition_page.dart b/lib/15/04/transition/fade_transition_page.dart similarity index 100% rename from lib/13/04/transition/fade_transition_page.dart rename to lib/15/04/transition/fade_transition_page.dart diff --git a/lib/13/04/transition/no_transition_page.dart b/lib/15/04/transition/no_transition_page.dart similarity index 100% rename from lib/13/04/transition/no_transition_page.dart rename to lib/15/04/transition/no_transition_page.dart diff --git a/lib/13/节点介绍.txt b/lib/15/节点介绍.txt similarity index 100% rename from lib/13/节点介绍.txt rename to lib/15/节点介绍.txt diff --git a/lib/13/04/app/navigation/app_router_delegate.dart b/lib/16/01/app/navigation/app_router_delegate.dart similarity index 98% rename from lib/13/04/app/navigation/app_router_delegate.dart rename to lib/16/01/app/navigation/app_router_delegate.dart index 587f207..7f9d92f 100644 --- a/lib/13/04/app/navigation/app_router_delegate.dart +++ b/lib/16/01/app/navigation/app_router_delegate.dart @@ -2,7 +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_page.dart'; diff --git a/lib/14/01/app/navigation/router/iroute.dart b/lib/16/01/app/navigation/router/iroute.dart similarity index 100% rename from lib/14/01/app/navigation/router/iroute.dart rename to lib/16/01/app/navigation/router/iroute.dart diff --git a/lib/14/01/app/navigation/views/app_navigation_rail.dart b/lib/16/01/app/navigation/views/app_navigation_rail.dart similarity index 100% rename from lib/14/01/app/navigation/views/app_navigation_rail.dart rename to lib/16/01/app/navigation/views/app_navigation_rail.dart diff --git a/lib/14/01/app/unit_app.dart b/lib/16/01/app/unit_app.dart similarity index 100% rename from lib/14/01/app/unit_app.dart rename to lib/16/01/app/unit_app.dart diff --git a/lib/16/01/main.dart b/lib/16/01/main.dart new file mode 100644 index 0000000..38c9d78 --- /dev/null +++ b/lib/16/01/main.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +import 'app/unit_app.dart'; +import 'app/navigation/app_router_delegate.dart'; + + + + + +void main() { + runApp(const UnitApp()); +} + + + + diff --git a/lib/14/01/pages/color/color_add_page.dart b/lib/16/01/pages/color/color_add_page.dart similarity index 100% rename from lib/14/01/pages/color/color_add_page.dart rename to lib/16/01/pages/color/color_add_page.dart diff --git a/lib/14/01/pages/color/color_page.dart b/lib/16/01/pages/color/color_page.dart similarity index 100% rename from lib/14/01/pages/color/color_page.dart rename to lib/16/01/pages/color/color_page.dart diff --git a/lib/14/01/pages/counter/counter_page.dart b/lib/16/01/pages/counter/counter_page.dart similarity index 100% rename from lib/14/01/pages/counter/counter_page.dart rename to lib/16/01/pages/counter/counter_page.dart diff --git a/lib/14/01/pages/empty/empty_page.dart b/lib/16/01/pages/empty/empty_page.dart similarity index 100% rename from lib/14/01/pages/empty/empty_page.dart rename to lib/16/01/pages/empty/empty_page.dart diff --git a/lib/14/01/pages/settings/settings_page.dart b/lib/16/01/pages/settings/settings_page.dart similarity index 100% rename from lib/14/01/pages/settings/settings_page.dart rename to lib/16/01/pages/settings/settings_page.dart diff --git a/lib/14/01/pages/user/user_page.dart b/lib/16/01/pages/user/user_page.dart similarity index 100% rename from lib/14/01/pages/user/user_page.dart rename to lib/16/01/pages/user/user_page.dart diff --git a/lib/13/go/raw_book/src/widgets/fade_transition_page.dart b/lib/16/01/transition/fade_transition_page.dart similarity index 100% rename from lib/13/go/raw_book/src/widgets/fade_transition_page.dart rename to lib/16/01/transition/fade_transition_page.dart diff --git a/lib/14/01/transition/no_transition_page.dart b/lib/16/01/transition/no_transition_page.dart similarity index 100% rename from lib/14/01/transition/no_transition_page.dart rename to lib/16/01/transition/no_transition_page.dart diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index f6f23bf..e71a16d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,6 @@ #include "generated_plugin_registrant.h" -#include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); - url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index f16b4c3..2e1de87 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 8236f57..cccf817 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,6 @@ import FlutterMacOS import Foundation -import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index bad937c..02b2213 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,22 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - adaptive_breakpoints: - dependency: transitive - description: - name: adaptive_breakpoints - sha256: "3aa6ef09074fe7824dfdc9a6d9f955c8a3bae0fb71c495cbd72f471a87699b4f" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.6" - adaptive_navigation: - dependency: "direct main" - description: - name: adaptive_navigation - sha256: "271d3e54147ce37b389c3d7d19777b4340e4ccd440d0349457c8b8db197b1c41" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.0.9" async: dependency: transitive description: @@ -53,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.flutter-io.cn" source: hosted - version: "1.17.2" + version: "1.18.0" cupertino_icons: dependency: "direct main" description: @@ -65,14 +49,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.5" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.5" fake_async: dependency: transitive description: @@ -112,19 +88,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - go_router: - dependency: "direct main" - description: - name: go_router - sha256: "2aa884667eeda3a1c461f31e72af1f77984ab0f29450d8fb12ec1f7bc53eea14" - url: "https://pub.flutter-io.cn" - source: hosted - version: "10.1.0" intl: dependency: transitive description: @@ -141,14 +104,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" - logging: - dependency: transitive - description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.2.0" matcher: dependency: transitive description: @@ -169,18 +124,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.1" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.0" + version: "1.10.0" path: dependency: transitive description: @@ -189,38 +136,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.8.3" - path_to_regexp: - dependency: "direct main" - description: - name: path_to_regexp - sha256: "169d78fbd55e61ea8873bcca545979f559d22238f66facdd7ef30870c7f53327" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.4.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.6" - provider: - dependency: "direct main" - description: - name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.0.5" - quiver: - dependency: "direct main" - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.2.1" sky_engine: dependency: transitive description: flutter @@ -238,18 +153,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.flutter-io.cn" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -270,89 +185,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.flutter-io.cn" source: hosted - version: "0.6.0" - toly_menu: - dependency: "direct main" - description: - path: "E:\\Projects\\Flutter\\packages\\toly_menu" - relative: false - source: path - version: "0.0.1" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.14" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.0" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.5" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.6" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.7" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.5" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.20" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.8" - url_strategy: - dependency: "direct main" - description: - name: url_strategy - sha256: "42b68b42a9864c4d710401add17ad06e28f1c1d5500c93b98c431f6b0ea4ab87" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.2.0" + version: "0.6.1" vector_math: dependency: transitive description: @@ -365,10 +201,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.1 <4.0.0" - flutter: ">=3.13.0" + dart: ">=3.2.0-194.0.dev <4.0.0" + flutter: ">=1.17.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5179f40..3f75079 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,15 +33,6 @@ dependencies: flutter_localizations: sdk: flutter flutter_colorpicker: ^1.0.3 -# window_manager: ^0.3.7 - adaptive_navigation: ^0.0.4 - go_router: ^10.1.0 - provider: 6.0.5 - url_launcher: ^6.0.7 - equatable: ^2.0.5 - url_strategy: ^0.2.0 - quiver: ^3.1.0 - path_to_regexp: ^0.4.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 diff --git a/test/parser/main.dart b/test/parser/main.dart index 160a4a5..572e9df 100644 --- a/test/parser/main.dart +++ b/test/parser/main.dart @@ -1,35 +1,35 @@ -import 'package:iroute/10/more_pop_icon.dart'; -import 'package:iroute/13/04/app/navigation/router/iroute.dart'; - -void main() { - bool b = MenuAction.help > MenuAction.about; - print(b); -} - - -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 MenuAction.about; +// print(b); +// } +// +// +// 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 + ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 4f78848..8b6d468 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,6 @@ #include "generated_plugin_registrant.h" -#include void RegisterPlugins(flutter::PluginRegistry* registry) { - UrlLauncherWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 88b22e5..b93c4c3 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST