v4
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
export 'toly_ui/toly_ui.dart';
|
export 'toly_ui/toly_ui.dart';
|
||||||
export 'windows/window_buttons.dart';
|
export 'windows/window_buttons.dart';
|
||||||
|
export 'windows/drag_to_move_area.dart';
|
||||||
45
lib/components/toly_ui/button/hover_icon_button.dart
Normal file
45
lib/components/toly_ui/button/hover_icon_button.dart
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class HoverIconButton extends StatefulWidget {
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
final IconData icon;
|
||||||
|
final double size;
|
||||||
|
final Color? hoverColor;
|
||||||
|
final Color? defaultColor;
|
||||||
|
const HoverIconButton({super.key,required this.onPressed ,required this.icon,this.hoverColor,this.size=24,this.defaultColor});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HoverIconButton> createState() => _HoverIconButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HoverIconButtonState extends State<HoverIconButton> {
|
||||||
|
|
||||||
|
bool _hover = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Color? color = (_hover)?widget.hoverColor??Theme.of(context).primaryColor:(widget.defaultColor??null);
|
||||||
|
|
||||||
|
return MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
onEnter: _onEnter,
|
||||||
|
onExit: _onExit,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: widget.onPressed,
|
||||||
|
child: Icon(widget.icon,size: widget.size,color: color,)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onEnter(PointerEnterEvent event) {
|
||||||
|
setState(() {
|
||||||
|
_hover = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onExit(PointerExitEvent event) {
|
||||||
|
setState(() {
|
||||||
|
_hover = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,10 +95,3 @@ class BreadcrumbItem {
|
|||||||
|
|
||||||
BreadcrumbItem( {this.to, required this.label,this.active=false,});
|
BreadcrumbItem( {this.to, required this.label,this.active=false,});
|
||||||
}
|
}
|
||||||
|
|
||||||
//<el-breadcrumb separator="/">
|
|
||||||
// <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
|
|
||||||
// <el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
|
|
||||||
// <el-breadcrumb-item>活动列表</el-breadcrumb-item>
|
|
||||||
// <el-breadcrumb-item>活动详情</el-breadcrumb-item>
|
|
||||||
// </el-breadcrumb>
|
|
||||||
|
|||||||
@@ -2,37 +2,20 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'menu_meta.dart';
|
import 'menu_meta.dart';
|
||||||
|
|
||||||
// final List<NavigationRailDestination> destinations = const [
|
|
||||||
// NavigationRailDestination(icon: Icon(Icons.color_lens_outlined), label: Text("颜色板")),
|
|
||||||
// NavigationRailDestination(icon: Icon(Icons.add_chart), label: Text("计数器")),
|
|
||||||
// NavigationRailDestination(icon: Icon(Icons.person), label: Text("我的")),
|
|
||||||
// NavigationRailDestination(icon: Icon(Icons.settings), label: Text("设置")),
|
|
||||||
// ];
|
|
||||||
|
|
||||||
const List<MenuMeta> kDeskNavBarMenus = [
|
|
||||||
MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined),
|
|
||||||
MenuMeta(
|
|
||||||
label: '计数器',
|
|
||||||
icon: Icons.add_chart,
|
|
||||||
),
|
|
||||||
MenuMeta(
|
|
||||||
label: '我的',
|
|
||||||
icon: Icons.person,
|
|
||||||
),
|
|
||||||
MenuMeta(label: '设置', icon: Icons.settings),
|
|
||||||
];
|
|
||||||
|
|
||||||
class TolyNavigationRail extends StatelessWidget {
|
class TolyNavigationRail extends StatelessWidget {
|
||||||
final ValueChanged<int> onDestinationSelected;
|
final ValueChanged<int> onDestinationSelected;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
final int? selectedIndex;
|
final int? selectedIndex;
|
||||||
final Widget? leading;
|
final Widget? leading;
|
||||||
|
final Widget? tail;
|
||||||
|
final List<MenuMeta> items;
|
||||||
const TolyNavigationRail({
|
const TolyNavigationRail({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.onDestinationSelected,
|
required this.onDestinationSelected,
|
||||||
required this.selectedIndex,
|
required this.selectedIndex,
|
||||||
|
required this.items,
|
||||||
this.leading,
|
this.leading,
|
||||||
|
this.tail,
|
||||||
required this.backgroundColor,
|
required this.backgroundColor,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@@ -46,11 +29,11 @@ class TolyNavigationRail extends StatelessWidget {
|
|||||||
if(leading!=null) leading!,
|
if(leading!=null) leading!,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: LeftNavigationMenu(
|
child: LeftNavigationMenu(
|
||||||
items: kDeskNavBarMenus,
|
items: items,
|
||||||
selectedIndex: selectedIndex,
|
selectedIndex: selectedIndex,
|
||||||
onTapItem: onDestinationSelected,
|
onTapItem: onDestinationSelected,
|
||||||
)),
|
)),
|
||||||
// if (selectedIndex == 0) HelpButton()
|
if(tail!=null) tail!,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
22
lib/components/windows/drag_to_move_area.dart
Normal file
22
lib/components/windows/drag_to_move_area.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
|
class DragToMoveWrap extends StatelessWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const DragToMoveWrap({
|
||||||
|
Key? key,
|
||||||
|
required this.child,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
|
onPanStart: (details) {
|
||||||
|
windowManager.startDragging();
|
||||||
|
},
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
import 'v3/app.dart';
|
import 'v4/app.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
@@ -14,6 +14,7 @@ void setSize() async{
|
|||||||
await windowManager.ensureInitialized();
|
await windowManager.ensureInitialized();
|
||||||
WindowOptions windowOptions = const WindowOptions(
|
WindowOptions windowOptions = const WindowOptions(
|
||||||
size: Size(800, 540),
|
size: Size(800, 540),
|
||||||
|
minimumSize: Size(600, 400),
|
||||||
center: true,
|
center: true,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
skipTaskbar: false,
|
skipTaskbar: false,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import '../../../pages/empty/empty_page.dart';
|
|||||||
import '../../../pages/settings/settings_page.dart';
|
import '../../../pages/settings/settings_page.dart';
|
||||||
import '../../../pages/counter/counter_page.dart';
|
import '../../../pages/counter/counter_page.dart';
|
||||||
import '../../../pages/sort/sort_page.dart';
|
import '../../../pages/sort/sort_page.dart';
|
||||||
import '../../../transition/fade_transition_page.dart';
|
import '../transition/fade_transition_page.dart';
|
||||||
import '../../../pages/color/color_add_page.dart';
|
import '../../../pages/color/color_add_page.dart';
|
||||||
|
|
||||||
const List<String> kDestinationsPaths = [
|
const List<String> kDestinationsPaths = [
|
||||||
|
|||||||
@@ -1,36 +1,31 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../router/app_router_delegate.dart';
|
import '../router/app_router_delegate.dart';
|
||||||
import 'app_navigation_rail.dart';
|
import 'app_navigation_rail.dart';
|
||||||
import 'background.dart';
|
import 'app_top_bar.dart';
|
||||||
import 'top_bar.dart';
|
|
||||||
|
|
||||||
class AppNavigation extends StatelessWidget {
|
class AppNavigation extends StatelessWidget {
|
||||||
const AppNavigation({super.key});
|
const AppNavigation({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
double px1 = 1/View.of(context).devicePixelRatio;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
// const Background(),
|
const AppNavigationRail(),
|
||||||
Row(
|
Expanded(
|
||||||
children: [
|
child: Column(
|
||||||
const AppNavigationRail(),
|
children: [
|
||||||
Expanded(
|
const AppTopBar(),
|
||||||
child: Column(
|
Divider(height: px1,),
|
||||||
children: [
|
Expanded(
|
||||||
TopBar(),
|
child: Router(
|
||||||
Divider(height: 1,),
|
routerDelegate: router,
|
||||||
Expanded(
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
child: Router(
|
),
|
||||||
routerDelegate: router,
|
|
||||||
backButtonDispatcher: RootBackButtonDispatcher(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:iroute/components/toly_ui/toly_ui.dart';
|
import 'package:iroute/components/components.dart';
|
||||||
import '../router/app_router_delegate.dart';
|
import '../router/app_router_delegate.dart';
|
||||||
|
|
||||||
class AppNavigationRail extends StatefulWidget {
|
class AppNavigationRail extends StatefulWidget {
|
||||||
@@ -10,11 +10,12 @@ class AppNavigationRail extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AppNavigationRailState extends State<AppNavigationRail> {
|
class _AppNavigationRailState extends State<AppNavigationRail> {
|
||||||
final List<NavigationRailDestination> destinations = const [
|
|
||||||
NavigationRailDestination(icon: Icon(Icons.color_lens_outlined), label: Text("颜色板")),
|
final List<MenuMeta> deskNavBarMenus = const [
|
||||||
NavigationRailDestination(icon: Icon(Icons.add_chart), label: Text("计数器")),
|
MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined),
|
||||||
NavigationRailDestination(icon: Icon(Icons.person), label: Text("我的")),
|
MenuMeta(label: '计数器', icon: Icons.add_chart),
|
||||||
NavigationRailDestination(icon: Icon(Icons.settings), label: Text("设置")),
|
MenuMeta(label: '我的', icon: Icons.person),
|
||||||
|
MenuMeta(label: '设置', icon: Icons.settings),
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -31,23 +32,19 @@ class _AppNavigationRailState extends State<AppNavigationRail> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TolyNavigationRail(
|
return DragToMoveWrap(
|
||||||
leading: Padding(
|
child: TolyNavigationRail(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 18.0),
|
items: deskNavBarMenus,
|
||||||
child: FlutterLogo(),
|
leading: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 18.0),
|
||||||
|
child: FlutterLogo(),
|
||||||
|
),
|
||||||
|
backgroundColor: const Color(0xff3975c6),
|
||||||
|
onDestinationSelected: _onDestinationSelected,
|
||||||
|
selectedIndex: router.activeIndex,
|
||||||
),
|
),
|
||||||
backgroundColor: const Color(0xff3975c6),
|
|
||||||
onDestinationSelected: _onDestinationSelected,
|
|
||||||
selectedIndex: router.activeIndex,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// return NavigationRail(
|
|
||||||
// backgroundColor: Colors.transparent,
|
|
||||||
// labelType: NavigationRailLabelType.all,
|
|
||||||
// onDestinationSelected: _onDestinationSelected,
|
|
||||||
// destinations: destinations,
|
|
||||||
// selectedIndex: router.activeIndex,
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onDestinationSelected(int index) {
|
void _onDestinationSelected(int index) {
|
||||||
|
|||||||
24
lib/v3/app/navigation/views/app_top_bar.dart
Normal file
24
lib/v3/app/navigation/views/app_top_bar.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/components.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppTopBar extends StatelessWidget {
|
||||||
|
const AppTopBar({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DragToMoveWrap(
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
height: 46,
|
||||||
|
child: const Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: SizedBox()),
|
||||||
|
WindowButtons()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class Background extends StatelessWidget {
|
|
||||||
const Background({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
gradient:
|
|
||||||
LinearGradient(transform: GradientRotation(pi / 2), colors: [
|
|
||||||
Color(0xffF1EFF1),
|
|
||||||
Color(0xffFFFFFF),
|
|
||||||
])),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'navigation/router/app_router_delegate.dart';
|
|
||||||
import 'navigation/views/app_navigation.dart';
|
import 'navigation/views/app_navigation.dart';
|
||||||
import 'navigation/views/app_navigation_rail.dart';
|
|
||||||
|
|
||||||
class UnitApp extends StatelessWidget {
|
class UnitApp extends StatelessWidget {
|
||||||
const UnitApp({super.key});
|
const UnitApp({super.key});
|
||||||
@@ -11,6 +9,7 @@ class UnitApp extends StatelessWidget {
|
|||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
|
scaffoldBackgroundColor: Colors.white,
|
||||||
fontFamily: "宋体",
|
fontFamily: "宋体",
|
||||||
appBarTheme: const AppBarTheme(
|
appBarTheme: const AppBarTheme(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
|||||||
12
lib/v3/pages/color/color_navigation.dart
Normal file
12
lib/v3/pages/color/color_navigation.dart
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ColorNavigation extends StatelessWidget {
|
||||||
|
const ColorNavigation({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Navigator(
|
||||||
|
pages: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
lib/v4/app.dart
Normal file
1
lib/v4/app.dart
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export 'app/unit_app.dart';
|
||||||
225
lib/v4/app/navigation/router/app_router_delegate.dart
Normal file
225
lib/v4/app/navigation/router/app_router_delegate.dart
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../pages/color/color_detail_page.dart';
|
||||||
|
import '../../../pages/color/color_page.dart';
|
||||||
|
import '../../../pages/empty/empty_page.dart';
|
||||||
|
import '../../../pages/settings/settings_page.dart';
|
||||||
|
import '../../../pages/counter/counter_page.dart';
|
||||||
|
import '../../../pages/sort/sort_page.dart';
|
||||||
|
import '../transition/fade_transition_page.dart';
|
||||||
|
import '../../../pages/color/color_add_page.dart';
|
||||||
|
|
||||||
|
const List<String> kDestinationsPaths = [
|
||||||
|
'/color',
|
||||||
|
'/counter',
|
||||||
|
'/user',
|
||||||
|
'/settings',
|
||||||
|
];
|
||||||
|
|
||||||
|
AppRouterDelegate router = AppRouterDelegate();
|
||||||
|
|
||||||
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier {
|
||||||
|
String _path = '/color';
|
||||||
|
|
||||||
|
String get path => _path;
|
||||||
|
|
||||||
|
int? get activeIndex {
|
||||||
|
if(path.startsWith('/color')) return 0;
|
||||||
|
if(path.startsWith('/counter')) return 1;
|
||||||
|
if(path.startsWith('/user')) return 2;
|
||||||
|
if(path.startsWith('/settings')) return 3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String,Completer<dynamic>> _completerMap = {};
|
||||||
|
|
||||||
|
Completer<dynamic>? completer;
|
||||||
|
|
||||||
|
final List<String> _alivePaths = [];
|
||||||
|
final Map<String,List<Page>> _alivePageMap = {};
|
||||||
|
|
||||||
|
void setPathKeepLive(String value){
|
||||||
|
_alivePageMap[value] = _buildPageByPath(value);
|
||||||
|
path = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String,dynamic> _pathExtraMap = {};
|
||||||
|
final List<Page> _livePages = [];
|
||||||
|
|
||||||
|
void setPathForData(String value,dynamic data){
|
||||||
|
_pathExtraMap[value] = data;
|
||||||
|
path = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> changePathForResult(String value) async{
|
||||||
|
Completer<dynamic> completer = Completer();
|
||||||
|
_completerMap[value] = completer;
|
||||||
|
path = value;
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
set path(String value) {
|
||||||
|
if (_path == value) return;
|
||||||
|
_path = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<Page> pages = [];
|
||||||
|
if(_alivePageMap.containsKey(path)){
|
||||||
|
pages = _alivePageMap[path]!;
|
||||||
|
}else{
|
||||||
|
for (var element in _alivePageMap.values) {
|
||||||
|
pages.addAll(element);
|
||||||
|
}
|
||||||
|
pages.addAll(_buildPageByPath(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Navigator(
|
||||||
|
onPopPage: _onPopPage,
|
||||||
|
pages: pages.toSet().toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> _buildPageByPath(String path) {
|
||||||
|
Widget? child;
|
||||||
|
if(path.startsWith('/color')){
|
||||||
|
// child = Navigator(
|
||||||
|
// pages: ,
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// );
|
||||||
|
return buildColorPages(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path == kDestinationsPaths[1]) {
|
||||||
|
child = const CounterPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[2]) {
|
||||||
|
child = const SortPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[3]) {
|
||||||
|
child = const SettingPage();
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
FadeTransitionPage(
|
||||||
|
key: ValueKey(path),
|
||||||
|
child: child ?? const EmptyPage(),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> buildColorPages(String path){
|
||||||
|
List<Page> result = [];
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
for (String segment in uri.pathSegments) {
|
||||||
|
if(segment == 'color'){
|
||||||
|
result.add( const FadeTransitionPage(
|
||||||
|
key: ValueKey('/color'),
|
||||||
|
child:ColorPage(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if(segment =='detail'){
|
||||||
|
final Map<String, String> queryParams = uri.queryParameters;
|
||||||
|
String? selectedColor = queryParams['color'];
|
||||||
|
|
||||||
|
if (selectedColor != null) {
|
||||||
|
Color color = Color(int.parse(selectedColor, radix: 16));
|
||||||
|
result.add( FadeTransitionPage(
|
||||||
|
key: const ValueKey('/color/detail'),
|
||||||
|
child:ColorDetailPage(color: color),
|
||||||
|
));
|
||||||
|
}else{
|
||||||
|
Color? selectedColor = _pathExtraMap[path];
|
||||||
|
if (selectedColor != null) {
|
||||||
|
result.add( FadeTransitionPage(
|
||||||
|
key: const ValueKey('/color/detail'),
|
||||||
|
child:ColorDetailPage(color: selectedColor),
|
||||||
|
));
|
||||||
|
_pathExtraMap.remove(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(segment == 'add'){
|
||||||
|
result.add( const FadeTransitionPage(
|
||||||
|
key: ValueKey('/color/add'),
|
||||||
|
child:ColorAddPage(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> popRoute() async {
|
||||||
|
print('=======popRoute=========');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onPopPage(Route route, result) {
|
||||||
|
if(_completerMap.containsKey(path)){
|
||||||
|
_completerMap[path]?.complete(result);
|
||||||
|
_completerMap.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
path = backPath(path);
|
||||||
|
return route.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
String backPath(String path){
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
if(uri.pathSegments.length==1) return path;
|
||||||
|
List<String> parts = List.of(uri.pathSegments)..removeLast();
|
||||||
|
return '/${parts.join('/')}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setNewRoutePath(configuration) async {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
|
||||||
|
//
|
||||||
|
// List<String> _value = ['/'];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> get value => _value;
|
||||||
|
//
|
||||||
|
// set value(List<String> value){
|
||||||
|
// _value = value;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Navigator(
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final Map<String, Page> _pageMap = const {
|
||||||
|
// '/': MaterialPage(child: HomePage()),
|
||||||
|
// 'a': MaterialPage(child: PageA()),
|
||||||
|
// 'b': MaterialPage(child: PageB()),
|
||||||
|
// 'c': MaterialPage(child: PageC()),
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// bool _onPopPage(Route route, result) {
|
||||||
|
// _value = List.of(_value)..removeLast();
|
||||||
|
// notifyListeners();
|
||||||
|
// return route.didPop(result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> setNewRoutePath(String configuration) async{
|
||||||
|
// }
|
||||||
|
// }
|
||||||
37
lib/v4/app/navigation/router/iroute.dart
Normal file
37
lib/v4/app/navigation/router/iroute.dart
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class IRoute {
|
||||||
|
final String path;
|
||||||
|
final List<IRoute> children;
|
||||||
|
|
||||||
|
const IRoute({required this.path, this.children = const []});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IRoute{path: $path, children: $children}';
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> list(){
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const List<IRoute> kDestinationsIRoutes = [
|
||||||
|
IRoute(
|
||||||
|
path: '/color',
|
||||||
|
children: [
|
||||||
|
IRoute(path: '/color/add'),
|
||||||
|
IRoute(path: '/color/detail'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/counter',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/user',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/settings',
|
||||||
|
),
|
||||||
|
];
|
||||||
53
lib/v4/app/navigation/transition/fade_transition_page.dart
Normal file
53
lib/v4/app/navigation/transition/fade_transition_page.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FadeTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
const FadeTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
this.duration = const Duration(milliseconds: 300),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) =>
|
||||||
|
PageBasedFadeTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageBasedFadeTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
final FadeTransitionPage<T> _page;
|
||||||
|
|
||||||
|
PageBasedFadeTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => _page.duration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
var curveTween = CurveTween(curve: Curves.easeIn);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation.drive(curveTween),
|
||||||
|
child: (settings as FadeTransitionPage).child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
47
lib/v4/app/navigation/transition/no_transition_page.dart
Normal file
47
lib/v4/app/navigation/transition/no_transition_page.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NoTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const NoTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) => NoTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
|
||||||
|
final NoTransitionPage<T> _page;
|
||||||
|
|
||||||
|
NoTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
return (settings as NoTransitionPage).child;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
34
lib/v4/app/navigation/views/app_navigation.dart
Normal file
34
lib/v4/app/navigation/views/app_navigation.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
import 'app_navigation_rail.dart';
|
||||||
|
import 'app_top_bar.dart';
|
||||||
|
|
||||||
|
class AppNavigation extends StatelessWidget {
|
||||||
|
const AppNavigation({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
double px1 = 1/View.of(context).devicePixelRatio;
|
||||||
|
return Scaffold(
|
||||||
|
body: Row(
|
||||||
|
children: [
|
||||||
|
const AppNavigationRail(),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const AppTopBar(),
|
||||||
|
Divider(height: px1,),
|
||||||
|
Expanded(
|
||||||
|
child: Router(
|
||||||
|
routerDelegate: router,
|
||||||
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
65
lib/v4/app/navigation/views/app_navigation_rail.dart
Normal file
65
lib/v4/app/navigation/views/app_navigation_rail.dart
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/components.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppNavigationRail extends StatefulWidget {
|
||||||
|
const AppNavigationRail({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppNavigationRail> createState() => _AppNavigationRailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppNavigationRailState extends State<AppNavigationRail> {
|
||||||
|
|
||||||
|
final List<MenuMeta> deskNavBarMenus = const [
|
||||||
|
MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined),
|
||||||
|
MenuMeta(label: '计数器', icon: Icons.add_chart),
|
||||||
|
MenuMeta(label: '我的', icon: Icons.person),
|
||||||
|
MenuMeta(label: '设置', icon: Icons.settings),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
router.addListener(_onRouterChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_onRouterChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DragToMoveWrap(
|
||||||
|
child: TolyNavigationRail(
|
||||||
|
items: deskNavBarMenus,
|
||||||
|
leading: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 18.0),
|
||||||
|
child: FlutterLogo(),
|
||||||
|
),
|
||||||
|
tail: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 6.0),
|
||||||
|
child: Text('V0.0.4',style: TextStyle(color: Colors.white,fontSize: 12),),
|
||||||
|
),
|
||||||
|
backgroundColor: const Color(0xff3975c6),
|
||||||
|
onDestinationSelected: _onDestinationSelected,
|
||||||
|
selectedIndex: router.activeIndex,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDestinationSelected(int index) {
|
||||||
|
if(index==1){
|
||||||
|
router.setPathKeepLive(kDestinationsPaths[index]);
|
||||||
|
}else{
|
||||||
|
router.path = kDestinationsPaths[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouterChange() {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
64
lib/v4/app/navigation/views/app_router_editor.dart
Normal file
64
lib/v4/app/navigation/views/app_router_editor.dart
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/toly_ui/button/hover_icon_button.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppRouterEditor extends StatefulWidget {
|
||||||
|
final ValueChanged<String>? onSubmit;
|
||||||
|
const AppRouterEditor({super.key, this.onSubmit});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppRouterEditor> createState() => _AppRouterEditorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppRouterEditorState extends State<AppRouterEditor> {
|
||||||
|
|
||||||
|
final TextEditingController _controller = TextEditingController();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_onRouteChange();
|
||||||
|
router.addListener(_onRouteChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouteChange() {
|
||||||
|
_controller.text=router.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
router.removeListener(_onRouteChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
child: CupertinoTextField(
|
||||||
|
controller: _controller,
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32),
|
||||||
|
placeholder: '输入路由地址导航',
|
||||||
|
onSubmitted: widget.onSubmit,
|
||||||
|
decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: HoverIconButton(
|
||||||
|
icon: Icons.directions_outlined,
|
||||||
|
defaultColor: Color(0xff68696B),
|
||||||
|
onPressed:()=>widget.onSubmit?.call(_controller.text),
|
||||||
|
size: 20
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
lib/v4/app/navigation/views/app_top_bar.dart
Normal file
104
lib/v4/app/navigation/views/app_top_bar.dart
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/components.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
import 'app_router_editor.dart';
|
||||||
|
|
||||||
|
class AppTopBar extends StatelessWidget {
|
||||||
|
const AppTopBar({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DragToMoveWrap(
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
height: 46,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
const RouterIndicator(),
|
||||||
|
Expanded(
|
||||||
|
child: Row(children: [
|
||||||
|
const Spacer(),
|
||||||
|
SizedBox(
|
||||||
|
width: 250,
|
||||||
|
child: AppRouterEditor(
|
||||||
|
onSubmit: (path) => router.path = path,
|
||||||
|
)),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.0),
|
||||||
|
child: VerticalDivider(
|
||||||
|
width: 32,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
])),
|
||||||
|
const WindowButtons()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RouterIndicator extends StatefulWidget {
|
||||||
|
const RouterIndicator({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RouterIndicator> createState() => _RouterIndicatorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> kRouteLabelMap = {
|
||||||
|
'/color': '颜色板',
|
||||||
|
'/color/add': '添加颜色',
|
||||||
|
'/color/detail': '颜色详情',
|
||||||
|
'/counter': '计数器',
|
||||||
|
'/user': '我的',
|
||||||
|
'/settings': '系统设置',
|
||||||
|
};
|
||||||
|
|
||||||
|
class _RouterIndicatorState extends State<RouterIndicator> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
router.addListener(_onRouterChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_onRouterChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TolyBreadcrumb(
|
||||||
|
items: pathToBreadcrumbItems(router.path),
|
||||||
|
onTapItem: (item) {
|
||||||
|
if (item.to != null) {
|
||||||
|
router.path = item.to!;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouterChange() {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BreadcrumbItem> pathToBreadcrumbItems(String path) {
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
List<BreadcrumbItem> result = [];
|
||||||
|
String to = '';
|
||||||
|
|
||||||
|
String distPath = '';
|
||||||
|
for (String segment in uri.pathSegments) {
|
||||||
|
distPath += '/$segment';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String segment in uri.pathSegments) {
|
||||||
|
to += '/$segment';
|
||||||
|
String label = kRouteLabelMap[to] ?? '未知路由';
|
||||||
|
result.add(BreadcrumbItem(to: to, label: label, active: to == distPath));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/v4/app/unit_app.dart
Normal file
30
lib/v4/app/unit_app.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'navigation/router/app_router_delegate.dart';
|
||||||
|
import 'navigation/views/app_navigation.dart';
|
||||||
|
import 'navigation/views/app_navigation_rail.dart';
|
||||||
|
|
||||||
|
class UnitApp extends StatelessWidget {
|
||||||
|
const UnitApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
fontFamily: "宋体",
|
||||||
|
scaffoldBackgroundColor: Colors.white,
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 0,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
))),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: AppNavigation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
102
lib/v4/pages/color/color_add_page.dart
Normal file
102
lib/v4/pages/color/color_add_page.dart
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
|
|
||||||
|
class ColorAddPage extends StatefulWidget {
|
||||||
|
const ColorAddPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorAddPage> createState() => _ColorAddPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorAddPageState extends State<ColorAddPage> {
|
||||||
|
late Color _color;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_color = randomColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String text = '# ${_color.value.toRadixString(16)}';
|
||||||
|
return Scaffold(
|
||||||
|
bottomNavigationBar: Container(
|
||||||
|
margin: EdgeInsets.only(right:20,bottom: 20),
|
||||||
|
// color: Colors.redAccent,
|
||||||
|
child: Row(
|
||||||
|
textDirection:TextDirection.rtl,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(onPressed: (){
|
||||||
|
Navigator.of(context).pop(_color);
|
||||||
|
|
||||||
|
}, child: Text('添加')),
|
||||||
|
SizedBox(width: 12,),
|
||||||
|
OutlinedButton(onPressed: (){
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}, child: Text('取消')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 10),
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: Icon(
|
||||||
|
Icons.sell_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _color,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ColorPicker(
|
||||||
|
colorPickerWidth:200,
|
||||||
|
// enableAlpha: false,
|
||||||
|
displayThumbColor:true,
|
||||||
|
pickerColor: _color,
|
||||||
|
paletteType: PaletteType.hueWheel,
|
||||||
|
onColorChanged: changeColor,
|
||||||
|
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Random _random = Random();
|
||||||
|
|
||||||
|
Color get randomColor {
|
||||||
|
return Color.fromARGB(
|
||||||
|
255,
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor() {
|
||||||
|
Navigator.of(context).pop(_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeColor(Color value) {
|
||||||
|
_color = value;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
34
lib/v4/pages/color/color_detail_page.dart
Normal file
34
lib/v4/pages/color/color_detail_page.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class ColorDetailPage extends StatelessWidget {
|
||||||
|
final Color color;
|
||||||
|
const ColorDetailPage({super.key, required this.color});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
const TextStyle style = TextStyle(
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white
|
||||||
|
);
|
||||||
|
String text = '# ${color.value.toRadixString(16)}';
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(
|
||||||
|
// systemOverlayStyle: SystemUiOverlayStyle(
|
||||||
|
// statusBarColor: Colors.transparent,
|
||||||
|
// statusBarIconBrightness: Brightness.light
|
||||||
|
// ),
|
||||||
|
// iconTheme: IconThemeData(color: Colors.white),
|
||||||
|
// titleTextStyle:TextStyle(color: Colors.white,fontSize: 18) ,
|
||||||
|
// backgroundColor: color,
|
||||||
|
// title: Text('颜色界面',),),
|
||||||
|
body: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: color,
|
||||||
|
child: Text(text ,style: style,),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
lib/v4/pages/color/color_page.dart
Normal file
54
lib/v4/pages/color/color_page.dart
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/project/colors_panel.dart';
|
||||||
|
import '../../app/navigation/router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class ColorPage extends StatefulWidget {
|
||||||
|
const ColorPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorPage> createState() => _ColorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorPageState extends State<ColorPage> {
|
||||||
|
final List<Color> _colors = [
|
||||||
|
Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange,
|
||||||
|
Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan,
|
||||||
|
Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent,
|
||||||
|
Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent,
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(title:const Text('颜色主页')),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _toAddPage,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
body: Align(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
child: ColorsPanel(
|
||||||
|
colors: _colors,
|
||||||
|
onSelect: _selectColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor(Color color){
|
||||||
|
String value = color.value.toRadixString(16);
|
||||||
|
router.path = '/color/detail?color=$value';
|
||||||
|
// router.setPathForData('/color/detail',color);
|
||||||
|
// router.setPathKeepLive('/color/detail?color=$value');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toAddPage() async {
|
||||||
|
Color? color = await router.changePathForResult('/color/add');
|
||||||
|
if (color != null) {
|
||||||
|
setState(() {
|
||||||
|
_colors.add(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
lib/v4/pages/counter/counter_page.dart
Normal file
43
lib/v4/pages/counter/counter_page.dart
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CounterPage extends StatefulWidget {
|
||||||
|
const CounterPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CounterPage> createState() => _CounterPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CounterPageState extends State<CounterPage> {
|
||||||
|
int _counter = 0;
|
||||||
|
|
||||||
|
void _incrementCounter() {
|
||||||
|
setState(() {
|
||||||
|
_counter++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const Text(
|
||||||
|
'You have pushed the button this many times:',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'$_counter',
|
||||||
|
style: Theme.of(context).textTheme.headlineMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _incrementCounter,
|
||||||
|
tooltip: 'Increment',
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/v4/pages/empty/empty_page.dart
Normal file
30
lib/v4/pages/empty/empty_page.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EmptyPage extends StatelessWidget {
|
||||||
|
const EmptyPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(
|
||||||
|
// title: Text('界面走丢了'),
|
||||||
|
// ),
|
||||||
|
body: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
direction: Axis.vertical,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.nearby_error,size: 64, color: Colors.grey),
|
||||||
|
Text(
|
||||||
|
'404 界面丢失',
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/v4/pages/settings/settings_page.dart
Normal file
11
lib/v4/pages/settings/settings_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingPage extends StatelessWidget {
|
||||||
|
const SettingPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('SettingPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
859
lib/v4/pages/sort/sort_page.dart
Normal file
859
lib/v4/pages/sort/sort_page.dart
Normal file
File diff suppressed because it is too large
Load Diff
11
lib/v4/pages/user/user_page.dart
Normal file
11
lib/v4/pages/user/user_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class UserPage extends StatelessWidget {
|
||||||
|
const UserPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('UserPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
1
lib/v5/app.dart
Normal file
1
lib/v5/app.dart
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export 'app/unit_app.dart';
|
||||||
229
lib/v5/app/navigation/router/app_router_delegate.dart
Normal file
229
lib/v5/app/navigation/router/app_router_delegate.dart
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../pages/color/color_detail_page.dart';
|
||||||
|
import '../../../pages/color/color_page.dart';
|
||||||
|
import '../../../pages/empty/empty_page.dart';
|
||||||
|
import '../../../pages/settings/settings_page.dart';
|
||||||
|
import '../../../pages/counter/counter_page.dart';
|
||||||
|
import '../../../pages/sort/sort_page.dart';
|
||||||
|
import '../transition/fade_transition_page.dart';
|
||||||
|
import '../../../pages/color/color_add_page.dart';
|
||||||
|
|
||||||
|
const List<String> kDestinationsPaths = [
|
||||||
|
'/color',
|
||||||
|
'/counter',
|
||||||
|
'/user',
|
||||||
|
'/settings',
|
||||||
|
];
|
||||||
|
|
||||||
|
AppRouterDelegate router = AppRouterDelegate();
|
||||||
|
|
||||||
|
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier {
|
||||||
|
String _path = '/color';
|
||||||
|
|
||||||
|
String get path => _path;
|
||||||
|
|
||||||
|
int? get activeIndex {
|
||||||
|
if(path.startsWith('/color')) return 0;
|
||||||
|
if(path.startsWith('/counter')) return 1;
|
||||||
|
if(path.startsWith('/user')) return 2;
|
||||||
|
if(path.startsWith('/settings')) return 3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String,Completer<dynamic>> _completerMap = {};
|
||||||
|
|
||||||
|
Completer<dynamic>? completer;
|
||||||
|
|
||||||
|
final List<String> _alivePaths = [];
|
||||||
|
final Map<String,Page> _alivePageMap = {};
|
||||||
|
|
||||||
|
void setPathKeepLive(String value){
|
||||||
|
if(!_alivePaths.contains(value)){
|
||||||
|
_alivePaths.add(value);
|
||||||
|
}
|
||||||
|
path = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String,dynamic> _pathExtraMap = {};
|
||||||
|
final List<Page> _livePages = [];
|
||||||
|
|
||||||
|
void setPathForData(String value,dynamic data){
|
||||||
|
_pathExtraMap[value] = data;
|
||||||
|
path = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> changePathForResult(String value) async{
|
||||||
|
Completer<dynamic> completer = Completer();
|
||||||
|
_completerMap[value] = completer;
|
||||||
|
path = value;
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
set path(String value) {
|
||||||
|
if (_path == value) return;
|
||||||
|
_path = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<Page> pages = _buildPageByPath(path);
|
||||||
|
|
||||||
|
if(_alivePaths.contains(path)){
|
||||||
|
_alivePageMap[path] = pages.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
pages.insertAll(0,_alivePageMap.values);
|
||||||
|
|
||||||
|
// if(!_livePaths.contains(path)){
|
||||||
|
// if(_livePaths.isNotEmpty){
|
||||||
|
// pages.addAll(_buildPageByPath(_livePaths.first));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pages.addAll();
|
||||||
|
|
||||||
|
return Navigator(
|
||||||
|
onPopPage: _onPopPage,
|
||||||
|
pages: pages.toSet().toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> _buildPageByPath(String path) {
|
||||||
|
if(path.startsWith('/color')){
|
||||||
|
return buildColorPages(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget? child;
|
||||||
|
if (path == kDestinationsPaths[1]) {
|
||||||
|
child = const CounterPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[2]) {
|
||||||
|
child = const SortPage();
|
||||||
|
}
|
||||||
|
if (path == kDestinationsPaths[3]) {
|
||||||
|
child = const SettingPage();
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
FadeTransitionPage(
|
||||||
|
key: ValueKey(path),
|
||||||
|
child: child ?? const EmptyPage(),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Page> buildColorPages(String path){
|
||||||
|
List<Page> result = [];
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
for (String segment in uri.pathSegments) {
|
||||||
|
if(segment == 'color'){
|
||||||
|
result.add( const FadeTransitionPage(
|
||||||
|
key: ValueKey('/color'),
|
||||||
|
child:ColorPage(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if(segment =='detail'){
|
||||||
|
// final Map<String, String> queryParams = uri.queryParameters;
|
||||||
|
// String? selectedColor = queryParams['color'];
|
||||||
|
//
|
||||||
|
// if (selectedColor != null) {
|
||||||
|
// Color color = Color(int.parse(selectedColor, radix: 16));
|
||||||
|
// result.add( FadeTransitionPage(
|
||||||
|
// key: const ValueKey('/color/detail'),
|
||||||
|
// child:ColorDetailPage(color: color),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
|
||||||
|
Color? selectedColor = _pathExtraMap[path];
|
||||||
|
if (selectedColor != null) {
|
||||||
|
result.add( FadeTransitionPage(
|
||||||
|
key: const ValueKey('/color/detail'),
|
||||||
|
child:ColorDetailPage(color: selectedColor),
|
||||||
|
));
|
||||||
|
_pathExtraMap.remove(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(segment == 'add'){
|
||||||
|
result.add( const FadeTransitionPage(
|
||||||
|
key: ValueKey('/color/add'),
|
||||||
|
child:ColorAddPage(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> popRoute() async {
|
||||||
|
print('=======popRoute=========');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _onPopPage(Route route, result) {
|
||||||
|
if(_completerMap.containsKey(path)){
|
||||||
|
_completerMap[path]?.complete(result);
|
||||||
|
_completerMap.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
path = backPath(path);
|
||||||
|
return route.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
String backPath(String path){
|
||||||
|
Uri uri = Uri.parse(path);
|
||||||
|
if(uri.pathSegments.length==1) return path;
|
||||||
|
List<String> parts = List.of(uri.pathSegments)..removeLast();
|
||||||
|
return '/${parts.join('/')}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setNewRoutePath(configuration) async {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
|
||||||
|
//
|
||||||
|
// List<String> _value = ['/'];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> get value => _value;
|
||||||
|
//
|
||||||
|
// set value(List<String> value){
|
||||||
|
// _value = value;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Navigator(
|
||||||
|
// onPopPage: _onPopPage,
|
||||||
|
// pages: _value.map((e) => _pageMap[e]!).toList(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final Map<String, Page> _pageMap = const {
|
||||||
|
// '/': MaterialPage(child: HomePage()),
|
||||||
|
// 'a': MaterialPage(child: PageA()),
|
||||||
|
// 'b': MaterialPage(child: PageB()),
|
||||||
|
// 'c': MaterialPage(child: PageC()),
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// bool _onPopPage(Route route, result) {
|
||||||
|
// _value = List.of(_value)..removeLast();
|
||||||
|
// notifyListeners();
|
||||||
|
// return route.didPop(result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> setNewRoutePath(String configuration) async{
|
||||||
|
// }
|
||||||
|
// }
|
||||||
37
lib/v5/app/navigation/router/iroute.dart
Normal file
37
lib/v5/app/navigation/router/iroute.dart
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class IRoute {
|
||||||
|
final String path;
|
||||||
|
final List<IRoute> children;
|
||||||
|
|
||||||
|
const IRoute({required this.path, this.children = const []});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IRoute{path: $path, children: $children}';
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> list(){
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const List<IRoute> kDestinationsIRoutes = [
|
||||||
|
IRoute(
|
||||||
|
path: '/color',
|
||||||
|
children: [
|
||||||
|
IRoute(path: '/color/add'),
|
||||||
|
IRoute(path: '/color/detail'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/counter',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/user',
|
||||||
|
),
|
||||||
|
IRoute(
|
||||||
|
path: '/settings',
|
||||||
|
),
|
||||||
|
];
|
||||||
53
lib/v5/app/navigation/transition/fade_transition_page.dart
Normal file
53
lib/v5/app/navigation/transition/fade_transition_page.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FadeTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
const FadeTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
this.duration = const Duration(milliseconds: 300),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) =>
|
||||||
|
PageBasedFadeTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageBasedFadeTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
final FadeTransitionPage<T> _page;
|
||||||
|
|
||||||
|
PageBasedFadeTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => _page.duration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
var curveTween = CurveTween(curve: Curves.easeIn);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation.drive(curveTween),
|
||||||
|
child: (settings as FadeTransitionPage).child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
47
lib/v5/app/navigation/transition/no_transition_page.dart
Normal file
47
lib/v5/app/navigation/transition/no_transition_page.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2021, the Flutter project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NoTransitionPage<T> extends Page<T> {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const NoTransitionPage({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Route<T> createRoute(BuildContext context) => NoTransitionRoute<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoTransitionRoute<T> extends PageRoute<T> {
|
||||||
|
|
||||||
|
final NoTransitionPage<T> _page;
|
||||||
|
|
||||||
|
NoTransitionRoute(this._page) : super(settings: _page);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get barrierLabel => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get maintainState => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
return (settings as NoTransitionPage).child;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation, Widget child) =>
|
||||||
|
child;
|
||||||
|
}
|
||||||
34
lib/v5/app/navigation/views/app_navigation.dart
Normal file
34
lib/v5/app/navigation/views/app_navigation.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
import 'app_navigation_rail.dart';
|
||||||
|
import 'app_top_bar.dart';
|
||||||
|
|
||||||
|
class AppNavigation extends StatelessWidget {
|
||||||
|
const AppNavigation({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
double px1 = 1/View.of(context).devicePixelRatio;
|
||||||
|
return Scaffold(
|
||||||
|
body: Row(
|
||||||
|
children: [
|
||||||
|
const AppNavigationRail(),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const AppTopBar(),
|
||||||
|
Divider(height: px1,),
|
||||||
|
Expanded(
|
||||||
|
child: Router(
|
||||||
|
routerDelegate: router,
|
||||||
|
backButtonDispatcher: RootBackButtonDispatcher(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
lib/v5/app/navigation/views/app_navigation_rail.dart
Normal file
64
lib/v5/app/navigation/views/app_navigation_rail.dart
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/components.dart';
|
||||||
|
import '../router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class AppNavigationRail extends StatefulWidget {
|
||||||
|
const AppNavigationRail({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppNavigationRail> createState() => _AppNavigationRailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppNavigationRailState extends State<AppNavigationRail> {
|
||||||
|
|
||||||
|
final List<MenuMeta> deskNavBarMenus = const [
|
||||||
|
MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined),
|
||||||
|
MenuMeta(label: '计数器', icon: Icons.add_chart),
|
||||||
|
MenuMeta(label: '我的', icon: Icons.person),
|
||||||
|
MenuMeta(label: '设置', icon: Icons.settings),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
router.addListener(_onRouterChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
router.removeListener(_onRouterChange);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DragToMoveWrap(
|
||||||
|
child: TolyNavigationRail(
|
||||||
|
items: deskNavBarMenus,
|
||||||
|
leading: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 18.0),
|
||||||
|
child: FlutterLogo(),
|
||||||
|
),
|
||||||
|
tail: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 6.0),
|
||||||
|
child: Text('V0.0.4',style: TextStyle(color: Colors.white,fontSize: 12),),
|
||||||
|
),
|
||||||
|
backgroundColor: const Color(0xff3975c6),
|
||||||
|
onDestinationSelected: _onDestinationSelected,
|
||||||
|
selectedIndex: router.activeIndex,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDestinationSelected(int index) {
|
||||||
|
if(index==1){
|
||||||
|
router.setPathKeepLive(kDestinationsPaths[index]);
|
||||||
|
}
|
||||||
|
router.path = kDestinationsPaths[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRouterChange() {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,22 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:iroute/components/components.dart';
|
import 'package:iroute/components/components.dart';
|
||||||
import '../router/app_router_delegate.dart';
|
import '../router/app_router_delegate.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
|
||||||
|
|
||||||
|
class AppTopBar extends StatelessWidget {
|
||||||
class TopBar extends StatelessWidget {
|
const AppTopBar({super.key});
|
||||||
const TopBar({super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DragToMoveAreaNoDouble(
|
return DragToMoveWrap(
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
height: 46,
|
height: 46,
|
||||||
child: Row(
|
child: const Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
SizedBox(width: 16),
|
||||||
width: 16,
|
Expanded(child: Align(
|
||||||
),
|
alignment: Alignment.centerLeft,
|
||||||
RouterIndicator(),
|
child: RouterIndicator())),
|
||||||
Spacer(),
|
|
||||||
WindowButtons()
|
WindowButtons()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -35,6 +32,16 @@ class RouterIndicator extends StatefulWidget {
|
|||||||
State<RouterIndicator> createState() => _RouterIndicatorState();
|
State<RouterIndicator> createState() => _RouterIndicatorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, String> kRouteLabelMap = {
|
||||||
|
'/color': '颜色板',
|
||||||
|
'/color/add': '添加颜色',
|
||||||
|
'/color/detail': '颜色详情',
|
||||||
|
'/counter': '计数器',
|
||||||
|
'/user': '我的',
|
||||||
|
'/settings': '系统设置',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class _RouterIndicatorState extends State<RouterIndicator> {
|
class _RouterIndicatorState extends State<RouterIndicator> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -42,14 +49,11 @@ class _RouterIndicatorState extends State<RouterIndicator> {
|
|||||||
router.addListener(_onRouterChange);
|
router.addListener(_onRouterChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> routeLabelMap = {
|
@override
|
||||||
'/color': '颜色板',
|
void dispose() {
|
||||||
'/color/add': '添加颜色',
|
router.removeListener(_onRouterChange);
|
||||||
'/color/detail': '颜色详情',
|
super.dispose();
|
||||||
'/counter': '计数器',
|
}
|
||||||
'/user': '我的',
|
|
||||||
'/settings': '系统设置',
|
|
||||||
};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -64,7 +68,6 @@ class _RouterIndicatorState extends State<RouterIndicator> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onRouterChange() {
|
void _onRouterChange() {
|
||||||
print('_onRouterChange');
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,28 +83,10 @@ class _RouterIndicatorState extends State<RouterIndicator> {
|
|||||||
|
|
||||||
for (String segment in uri.pathSegments) {
|
for (String segment in uri.pathSegments) {
|
||||||
to += '/$segment';
|
to += '/$segment';
|
||||||
result.add(BreadcrumbItem(to: to, label: routeLabelMap[to] ?? '未知路由',active: to==distPath));
|
String label = kRouteLabelMap[to] ?? '未知路由';
|
||||||
|
result.add(BreadcrumbItem(to: to, label: label,active: to==distPath));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DragToMoveAreaNoDouble extends StatelessWidget {
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const DragToMoveAreaNoDouble({
|
|
||||||
Key? key,
|
|
||||||
required this.child,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
behavior: HitTestBehavior.translucent,
|
|
||||||
onPanStart: (details) {
|
|
||||||
windowManager.startDragging();
|
|
||||||
},
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
30
lib/v5/app/unit_app.dart
Normal file
30
lib/v5/app/unit_app.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'navigation/router/app_router_delegate.dart';
|
||||||
|
import 'navigation/views/app_navigation.dart';
|
||||||
|
import 'navigation/views/app_navigation_rail.dart';
|
||||||
|
|
||||||
|
class UnitApp extends StatelessWidget {
|
||||||
|
const UnitApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return MaterialApp(
|
||||||
|
// routerDelegate: router,
|
||||||
|
theme: ThemeData(
|
||||||
|
fontFamily: "宋体",
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 0,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
))),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: AppNavigation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
102
lib/v5/pages/color/color_add_page.dart
Normal file
102
lib/v5/pages/color/color_add_page.dart
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
|
|
||||||
|
class ColorAddPage extends StatefulWidget {
|
||||||
|
const ColorAddPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorAddPage> createState() => _ColorAddPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorAddPageState extends State<ColorAddPage> {
|
||||||
|
late Color _color;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_color = randomColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String text = '# ${_color.value.toRadixString(16)}';
|
||||||
|
return Scaffold(
|
||||||
|
bottomNavigationBar: Container(
|
||||||
|
margin: EdgeInsets.only(right:20,bottom: 20),
|
||||||
|
// color: Colors.redAccent,
|
||||||
|
child: Row(
|
||||||
|
textDirection:TextDirection.rtl,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(onPressed: (){
|
||||||
|
Navigator.of(context).pop(_color);
|
||||||
|
|
||||||
|
}, child: Text('添加')),
|
||||||
|
SizedBox(width: 12,),
|
||||||
|
OutlinedButton(onPressed: (){
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}, child: Text('取消')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 10),
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: Icon(
|
||||||
|
Icons.sell_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _color,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ColorPicker(
|
||||||
|
colorPickerWidth:200,
|
||||||
|
// enableAlpha: false,
|
||||||
|
displayThumbColor:true,
|
||||||
|
pickerColor: _color,
|
||||||
|
paletteType: PaletteType.hueWheel,
|
||||||
|
onColorChanged: changeColor,
|
||||||
|
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Random _random = Random();
|
||||||
|
|
||||||
|
Color get randomColor {
|
||||||
|
return Color.fromARGB(
|
||||||
|
255,
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
_random.nextInt(256),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor() {
|
||||||
|
Navigator.of(context).pop(_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeColor(Color value) {
|
||||||
|
_color = value;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
34
lib/v5/pages/color/color_detail_page.dart
Normal file
34
lib/v5/pages/color/color_detail_page.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class ColorDetailPage extends StatelessWidget {
|
||||||
|
final Color color;
|
||||||
|
const ColorDetailPage({super.key, required this.color});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
const TextStyle style = TextStyle(
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white
|
||||||
|
);
|
||||||
|
String text = '# ${color.value.toRadixString(16)}';
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(
|
||||||
|
// systemOverlayStyle: SystemUiOverlayStyle(
|
||||||
|
// statusBarColor: Colors.transparent,
|
||||||
|
// statusBarIconBrightness: Brightness.light
|
||||||
|
// ),
|
||||||
|
// iconTheme: IconThemeData(color: Colors.white),
|
||||||
|
// titleTextStyle:TextStyle(color: Colors.white,fontSize: 18) ,
|
||||||
|
// backgroundColor: color,
|
||||||
|
// title: Text('颜色界面',),),
|
||||||
|
body: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: color,
|
||||||
|
child: Text(text ,style: style,),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
lib/v5/pages/color/color_page.dart
Normal file
54
lib/v5/pages/color/color_page.dart
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:iroute/components/project/colors_panel.dart';
|
||||||
|
import '../../app/navigation/router/app_router_delegate.dart';
|
||||||
|
|
||||||
|
class ColorPage extends StatefulWidget {
|
||||||
|
const ColorPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ColorPage> createState() => _ColorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorPageState extends State<ColorPage> {
|
||||||
|
final List<Color> _colors = [
|
||||||
|
Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange,
|
||||||
|
Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan,
|
||||||
|
Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent,
|
||||||
|
Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent,
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
// appBar: AppBar(title:const Text('颜色主页')),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _toAddPage,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
body: Align(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
child: ColorsPanel(
|
||||||
|
colors: _colors,
|
||||||
|
onSelect: _selectColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor(Color color){
|
||||||
|
// String value = color.value.toRadixString(16);
|
||||||
|
// router.path = '/color/detail?color=$value';
|
||||||
|
router.setPathForData('/color/detail',color);
|
||||||
|
// router.setPathKeepLive('/color/detail?color=$value');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toAddPage() async {
|
||||||
|
Color? color = await router.changePathForResult('/color/add');
|
||||||
|
if (color != null) {
|
||||||
|
setState(() {
|
||||||
|
_colors.add(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
lib/v5/pages/counter/counter_page.dart
Normal file
43
lib/v5/pages/counter/counter_page.dart
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CounterPage extends StatefulWidget {
|
||||||
|
const CounterPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CounterPage> createState() => _CounterPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CounterPageState extends State<CounterPage> {
|
||||||
|
int _counter = 0;
|
||||||
|
|
||||||
|
void _incrementCounter() {
|
||||||
|
setState(() {
|
||||||
|
_counter++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const Text(
|
||||||
|
'You have pushed the button this many times:',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'$_counter',
|
||||||
|
style: Theme.of(context).textTheme.headlineMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _incrementCounter,
|
||||||
|
tooltip: 'Increment',
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lib/v5/pages/empty/empty_page.dart
Normal file
30
lib/v5/pages/empty/empty_page.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EmptyPage extends StatelessWidget {
|
||||||
|
const EmptyPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('界面走丢了'),
|
||||||
|
),
|
||||||
|
body: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
direction: Axis.vertical,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.nearby_error,size: 64, color: Colors.grey),
|
||||||
|
Text(
|
||||||
|
'404 界面丢失',
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
lib/v5/pages/settings/settings_page.dart
Normal file
11
lib/v5/pages/settings/settings_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingPage extends StatelessWidget {
|
||||||
|
const SettingPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('SettingPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
859
lib/v5/pages/sort/sort_page.dart
Normal file
859
lib/v5/pages/sort/sort_page.dart
Normal file
File diff suppressed because it is too large
Load Diff
11
lib/v5/pages/user/user_page.dart
Normal file
11
lib/v5/pages/user/user_page.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class UserPage extends StatelessWidget {
|
||||||
|
const UserPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body:Center(child: Text('UserPage')));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user