路由生命周期状态
This commit is contained in:
46
lib/10/app_info.dart
Normal file
46
lib/10/app_info.dart
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AppInfo extends StatelessWidget {
|
||||||
|
const AppInfo({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const String msg = 'FlutterUnit 是一个辅助开发者,了解 Flutter 组件和编程技术的开源项目。 ';
|
||||||
|
const String msg2 = '由张风捷特烈维护,开源地址:\n https://github.com/toly1994328/FlutterUnit ';
|
||||||
|
|
||||||
|
double height = MediaQuery.of(context).size.height;
|
||||||
|
return SizedBox(
|
||||||
|
height: height*(1-0.618),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
centerTitle: true,
|
||||||
|
leading: Align(child: FlutterLogo()),
|
||||||
|
actions: [
|
||||||
|
CloseButton()
|
||||||
|
],
|
||||||
|
title: Column(
|
||||||
|
children: [
|
||||||
|
Text('FlutterUnit',style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold)),
|
||||||
|
Text('v2.9.3',style: TextStyle(fontSize: 12,),),
|
||||||
|
],
|
||||||
|
),),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20.0,vertical: 10),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// direction: Axis.vertical,
|
||||||
|
children: [
|
||||||
|
Text(msg,style: TextStyle(color: Colors.grey),),
|
||||||
|
const SizedBox(height: 8,),
|
||||||
|
Text(msg2,style: TextStyle(color: Colors.grey),),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
107
lib/10/cupertino_context_menu_demo.dart
Normal file
107
lib/10/cupertino_context_menu_demo.dart
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 2014 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/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Flutter code sample for [CupertinoContextMenu].
|
||||||
|
|
||||||
|
final DecorationTween _tween = DecorationTween(
|
||||||
|
begin: BoxDecoration(
|
||||||
|
color: CupertinoColors.systemPurple,
|
||||||
|
boxShadow: const <BoxShadow>[],
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
),
|
||||||
|
end: BoxDecoration(
|
||||||
|
color: CupertinoColors.systemPurple,
|
||||||
|
boxShadow: CupertinoContextMenu.kEndBoxShadow,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
class CupertinoContextMenuDemo extends StatelessWidget {
|
||||||
|
const CupertinoContextMenuDemo({super.key});
|
||||||
|
|
||||||
|
// Or just do this inline in the builder below?
|
||||||
|
static Animation<Decoration> _boxDecorationAnimation(
|
||||||
|
Animation<double> animation) {
|
||||||
|
return _tween.animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: animation,
|
||||||
|
curve: Interval(
|
||||||
|
0.0,
|
||||||
|
CupertinoContextMenu.animationOpensAt,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CupertinoPageScaffold(
|
||||||
|
navigationBar: const CupertinoNavigationBar(
|
||||||
|
middle: Text('CupertinoContextMenu 案例'),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
child: CupertinoContextMenu.builder(
|
||||||
|
actions: <Widget>[
|
||||||
|
CupertinoContextMenuAction(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
isDefaultAction: true,
|
||||||
|
trailingIcon: CupertinoIcons.doc_on_clipboard_fill,
|
||||||
|
child: const Text('Copy'),
|
||||||
|
),
|
||||||
|
CupertinoContextMenuAction(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
trailingIcon: CupertinoIcons.share,
|
||||||
|
child: const Text('Share'),
|
||||||
|
),
|
||||||
|
CupertinoContextMenuAction(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
trailingIcon: CupertinoIcons.heart,
|
||||||
|
child: const Text('Favorite'),
|
||||||
|
),
|
||||||
|
CupertinoContextMenuAction(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
isDestructiveAction: true,
|
||||||
|
trailingIcon: CupertinoIcons.delete,
|
||||||
|
child: const Text('Delete'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
builder: (BuildContext context, Animation<double> animation) {
|
||||||
|
final Animation<Decoration> boxDecorationAnimation =
|
||||||
|
_boxDecorationAnimation(animation);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
decoration:
|
||||||
|
animation.value < CupertinoContextMenu.animationOpensAt
|
||||||
|
? boxDecorationAnimation.value
|
||||||
|
: null,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CupertinoColors.systemPurple,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
),
|
||||||
|
child: const FlutterLogo(size: 250.0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
lib/10/dropdown_button_color.dart
Normal file
83
lib/10/dropdown_button_color.dart
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
// Copyright 2014 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';
|
||||||
|
|
||||||
|
/// Flutter code sample for [DropdownButton.selectedItemBuilder].
|
||||||
|
|
||||||
|
const Map<String, Color> kColors = <String, Color>{
|
||||||
|
'红色': Colors.red,
|
||||||
|
'黄色': Colors.yellowAccent,
|
||||||
|
'蓝色': Colors.blue,
|
||||||
|
'绿色': Colors.greenAccent,
|
||||||
|
'橙色': Colors.orange,
|
||||||
|
'紫色': Colors.purple,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DropdownButtonColor extends StatefulWidget {
|
||||||
|
const DropdownButtonColor({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DropdownButtonColor> createState() => _DropdownButtonColorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DropdownButtonColorState extends State<DropdownButtonColor> {
|
||||||
|
String selectedItem = kColors.keys.first;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Text('选择颜色:', style: Theme.of(context).textTheme.bodyLarge),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
value: selectedItem,
|
||||||
|
onChanged: (String? value) {
|
||||||
|
setState(() => selectedItem = value!);
|
||||||
|
},
|
||||||
|
selectedItemBuilder: _buildSelectItem,
|
||||||
|
items: _buildItems(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DropdownMenuItem<String>> _buildItems(){
|
||||||
|
return kColors.keys.map<DropdownMenuItem<String>>((String key) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: key,
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 4,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 14,
|
||||||
|
height: 14,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kColors[key],
|
||||||
|
borderRadius: BorderRadius.circular(2)),
|
||||||
|
),
|
||||||
|
Text(key),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildSelectItem(BuildContext context) {
|
||||||
|
return kColors.values.map<Widget>((Color color) {
|
||||||
|
return Align(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color,
|
||||||
|
borderRadius: BorderRadius.circular(2)),
|
||||||
|
constraints: const BoxConstraints(minWidth: 24,maxHeight: 24),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
137
lib/10/main.dart
Normal file
137
lib/10/main.dart
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
|
||||||
|
import 'app_info.dart';
|
||||||
|
import 'cupertino_context_menu_demo.dart';
|
||||||
|
import 'dropdown_button_color.dart';
|
||||||
|
import 'more_pop_icon.dart';
|
||||||
|
import 'search_anchor_demo.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||||
|
supportedLocales: const [
|
||||||
|
Locale('zh', 'CN'),
|
||||||
|
],
|
||||||
|
locale: const Locale('zh', 'CN'),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
theme: ThemeData(
|
||||||
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const HomePage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HomePage extends StatefulWidget {
|
||||||
|
const HomePage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HomePage> createState() => _HomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomePageState extends State<HomePage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("弹出层测试"),
|
||||||
|
actions: [
|
||||||
|
MorePopIcon(onTapItem: _onTapItem,)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: showConformDialog,
|
||||||
|
child: Text('关于应用'),
|
||||||
|
),
|
||||||
|
DropdownButtonColor(),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _showModalBottomSheet,
|
||||||
|
child: Text('showModalBottomSheet'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _showCupertinoModalPopup,
|
||||||
|
child: Text('showCupertinoModalPopup'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _toSearchAnchor,
|
||||||
|
child: Text('SearchAnchor 案例'),
|
||||||
|
), ElevatedButton(
|
||||||
|
onPressed: _toCupertinoContextMenu,
|
||||||
|
child: Text('CupertinoContextMenu 案例'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showConformDialog(){
|
||||||
|
showDialog(context: context, builder: _buildAbout);
|
||||||
|
// showCupertinoModalPopup(context: context, builder: builder)
|
||||||
|
// showCupertinoDialog(context: context, builder: _buildAbout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showModalBottomSheet(){
|
||||||
|
showModalBottomSheet(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8)
|
||||||
|
),
|
||||||
|
context: context, builder: (_)=>AppInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showCupertinoModalPopup(){
|
||||||
|
showCupertinoModalPopup(
|
||||||
|
context: context, builder: (_)=>Material(child: const AppInfo()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAbout(BuildContext context){
|
||||||
|
const String msg = 'FlutterUnit 是一个辅助开发者,了解 Flutter 组件和编程技术的开源项目。';
|
||||||
|
return const AboutDialog(
|
||||||
|
applicationName: "FlutterUnit",
|
||||||
|
applicationVersion: "v2.9.3",
|
||||||
|
applicationIcon: FlutterLogo(),
|
||||||
|
children: [
|
||||||
|
Text(msg,style: TextStyle(color: Colors.grey),)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTapItem(MenuAction value) {
|
||||||
|
print(value.label);
|
||||||
|
switch(value){
|
||||||
|
case MenuAction.setting:
|
||||||
|
break;
|
||||||
|
case MenuAction.about:
|
||||||
|
showConformDialog();
|
||||||
|
break;
|
||||||
|
case MenuAction.help:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toSearchAnchor() {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (_)=>SearchAnchorDemo()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toCupertinoContextMenu() {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (_)=>CupertinoContextMenuDemo()));
|
||||||
|
}
|
||||||
|
}
|
||||||
58
lib/10/more_pop_icon.dart
Normal file
58
lib/10/more_pop_icon.dart
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
enum MenuAction implements Comparable<MenuAction> {
|
||||||
|
setting(label: '应用设置', iconData: Icons.settings),
|
||||||
|
about(label: '关于应用', iconData: Icons.info),
|
||||||
|
help(label: '帮助中心', iconData: Icons.help);
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final IconData iconData;
|
||||||
|
|
||||||
|
const MenuAction({
|
||||||
|
required this.label,
|
||||||
|
required this.iconData,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int compareTo(MenuAction other) => label.compareTo(other.label);
|
||||||
|
|
||||||
|
bool operator >(MenuAction other) {
|
||||||
|
return compareTo(other) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MorePopIcon extends StatelessWidget {
|
||||||
|
final ValueChanged<MenuAction> onTapItem;
|
||||||
|
const MorePopIcon({super.key, required this.onTapItem});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopupMenuButton<MenuAction>(
|
||||||
|
itemBuilder: _buildItem,
|
||||||
|
onSelected: onTapItem,
|
||||||
|
icon: const Icon(Icons.more_vert_outlined),
|
||||||
|
position: PopupMenuPosition.under,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PopupMenuEntry<MenuAction>> _buildItem(BuildContext context) {
|
||||||
|
return MenuAction.values
|
||||||
|
.map((MenuAction action) => PopupMenuItem<MenuAction>(
|
||||||
|
height: 35,
|
||||||
|
value: action,
|
||||||
|
child: Center(
|
||||||
|
child: Wrap(
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
spacing: 6,
|
||||||
|
children: [
|
||||||
|
Text(action.label),
|
||||||
|
Icon(action.iconData, size: 18),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
162
lib/10/search_anchor_demo.dart
Normal file
162
lib/10/search_anchor_demo.dart
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
// Copyright 2014 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';
|
||||||
|
|
||||||
|
class SearchAnchorDemo extends StatefulWidget {
|
||||||
|
const SearchAnchorDemo({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SearchAnchorDemo> createState() => _SearchAnchorDemoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchAnchorDemoState extends State<SearchAnchorDemo> {
|
||||||
|
Color? selectedColorSeed;
|
||||||
|
List<ColorLabel> searchHistory = <ColorLabel>[];
|
||||||
|
|
||||||
|
Iterable<Widget> getHistoryList(SearchController controller) {
|
||||||
|
return searchHistory.map(
|
||||||
|
(ColorLabel color) => ListTile(
|
||||||
|
leading: const Icon(Icons.history),
|
||||||
|
title: Text(color.label),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.call_missed),
|
||||||
|
onPressed: () {
|
||||||
|
controller.text = color.label;
|
||||||
|
controller.selection = TextSelection.collapsed(offset: controller.text.length);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable<Widget> getSuggestions(SearchController controller) {
|
||||||
|
final String input = controller.value.text;
|
||||||
|
return ColorLabel.values.where((ColorLabel color) => color.label.contains(input)).map(
|
||||||
|
(ColorLabel filteredColor) => ListTile(
|
||||||
|
leading: CircleAvatar(backgroundColor: filteredColor.color),
|
||||||
|
title: Text(filteredColor.label),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.call_missed),
|
||||||
|
onPressed: () {
|
||||||
|
controller.text = filteredColor.label;
|
||||||
|
controller.selection = TextSelection.collapsed(offset: controller.text.length);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
controller.closeView(filteredColor.label);
|
||||||
|
handleSelection(filteredColor);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSelection(ColorLabel selectedColor) {
|
||||||
|
setState(() {
|
||||||
|
selectedColorSeed = selectedColor.color;
|
||||||
|
if (searchHistory.length >= 5) {
|
||||||
|
searchHistory.removeLast();
|
||||||
|
}
|
||||||
|
searchHistory.insert(0, selectedColor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String,Color> colorMaps(ColorScheme colors) => {
|
||||||
|
'primary':colors.primary ,
|
||||||
|
'secondary':colors.secondary ,
|
||||||
|
'inverseSurface':colors.inverseSurface ,
|
||||||
|
'background':colors.background ,
|
||||||
|
|
||||||
|
|
||||||
|
'onPrimaryContainer':colors.onPrimaryContainer ,
|
||||||
|
'onErrorContainer':colors.onErrorContainer ,
|
||||||
|
'onBackground':colors.onBackground ,
|
||||||
|
'onTertiaryContainer':colors.onTertiaryContainer ,
|
||||||
|
|
||||||
|
|
||||||
|
'error':colors.error ,
|
||||||
|
'inversePrimary':colors.inversePrimary ,
|
||||||
|
'primaryContainer':colors.primaryContainer ,
|
||||||
|
'errorContainer':colors.errorContainer ,
|
||||||
|
|
||||||
|
'onPrimary':colors.onPrimary ,
|
||||||
|
'onSecondary':colors.onSecondary ,
|
||||||
|
'onError':colors.onError ,
|
||||||
|
'onTertiary':colors.onTertiary ,
|
||||||
|
'onSurfaceVariant':colors.onSurfaceVariant ,
|
||||||
|
'shadow':colors.shadow ,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: selectedColorSeed);
|
||||||
|
final ColorScheme colors = themeData.colorScheme;
|
||||||
|
Map<String,Color> data = colorMaps(colors);
|
||||||
|
SizedBox cardSize = const SizedBox(
|
||||||
|
width: 80,
|
||||||
|
height: 30,
|
||||||
|
child: Text(''),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('搜索颜色')),
|
||||||
|
body: Align(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
SearchAnchor.bar(
|
||||||
|
barHintText: '输入颜色',
|
||||||
|
suggestionsBuilder: (BuildContext context, SearchController controller) {
|
||||||
|
if (controller.text.isEmpty) {
|
||||||
|
if (searchHistory.isNotEmpty) {
|
||||||
|
return getHistoryList(controller);
|
||||||
|
}
|
||||||
|
return <Widget>[Center(child: Text('暂无历史记录.', style: TextStyle(color: colors.outline)))];
|
||||||
|
}
|
||||||
|
return getSuggestions(controller);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cardSize,
|
||||||
|
Wrap(
|
||||||
|
children: data.keys.map((key) => Card(color: data[key], child: SizedBox(
|
||||||
|
width: 80,
|
||||||
|
height: 30,
|
||||||
|
child: Center(child: Text(key,style: TextStyle(fontSize: 8,color: Colors.white,shadows: [
|
||||||
|
BoxShadow(color: Colors.black,offset: Offset(.1,.1),blurRadius: 2)
|
||||||
|
]),)),
|
||||||
|
))).toList(),
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum ColorLabel {
|
||||||
|
red('red', Colors.red),
|
||||||
|
orange('orange', Colors.orange),
|
||||||
|
yellow('yellow', Colors.yellow),
|
||||||
|
green('green', Colors.green),
|
||||||
|
blue('blue', Colors.blue),
|
||||||
|
indigo('indigo', Colors.indigo),
|
||||||
|
violet('violet', Color(0xFF8F00FF)),
|
||||||
|
purple('purple', Colors.purple),
|
||||||
|
pink('pink', Colors.pink),
|
||||||
|
silver('silver', Color(0xFF808080)),
|
||||||
|
gold('gold', Color(0xFFFFD700)),
|
||||||
|
beige('beige', Color(0xFFF5F5DC)),
|
||||||
|
brown('brown', Colors.brown),
|
||||||
|
grey('grey', Colors.grey),
|
||||||
|
black('black', Colors.black),
|
||||||
|
white('white', Colors.white);
|
||||||
|
|
||||||
|
const ColorLabel(this.label, this.color);
|
||||||
|
final String label;
|
||||||
|
final Color color;
|
||||||
|
}
|
||||||
24
lib/11/color_detail.dart
Normal file
24
lib/11/color_detail.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ColorDetailPage extends StatelessWidget {
|
||||||
|
final Color color;
|
||||||
|
const ColorDetailPage({super.key, required this.color});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: color,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
iconTheme: IconThemeData(color: Colors.white),
|
||||||
|
titleTextStyle: TextStyle(color: Colors.white,fontSize: 16,fontWeight: FontWeight.bold),
|
||||||
|
backgroundColor: color,
|
||||||
|
title: Text('颜色详情页'),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Text( '#${color.value.toRadixString(16)}',style: TextStyle(color: Colors.white,fontSize: 26,fontWeight: FontWeight.bold),),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
66
lib/11/color_page.dart
Normal file
66
lib/11/color_page.dart
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../common/components/colors_panel.dart';
|
||||||
|
import 'color_detail.dart';
|
||||||
|
import 'transition.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: ColorsPanel(
|
||||||
|
colors: _colors,
|
||||||
|
onSelect: _selectColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectColor(Color color) {
|
||||||
|
Route route = PageRouteBuilder<void>(
|
||||||
|
barrierColor: Colors.white,
|
||||||
|
pageBuilder: (_, __, ___) => ColorDetailPage(color:color),
|
||||||
|
transitionsBuilder: kSlideBottomToTopWithSecondary,
|
||||||
|
);
|
||||||
|
Navigator.push(context, route);
|
||||||
|
// Navigator.push(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(builder: (_)=>ColorDetailPage(color:color)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toAddPage() {
|
||||||
|
}
|
||||||
|
}
|
||||||
72
lib/11/main.dart
Normal file
72
lib/11/main.dart
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:iroute/11/transition.dart';
|
||||||
|
|
||||||
|
import 'color_page.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||||
|
supportedLocales: const [
|
||||||
|
Locale('zh', 'CN'),
|
||||||
|
],
|
||||||
|
locale: const Locale('zh', 'CN'),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
theme: ThemeData(
|
||||||
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const HomePage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HomePage extends StatefulWidget {
|
||||||
|
const HomePage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HomePage> createState() => _HomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomePageState extends State<HomePage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("Cose 酷色"),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _toColorHome,
|
||||||
|
child: Text('打开颜色界面'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toColorHome() {
|
||||||
|
Route route = PageRouteBuilder<void>(
|
||||||
|
barrierColor: Colors.white,
|
||||||
|
pageBuilder: (_, __, ___) => const ColorPage(),
|
||||||
|
transitionsBuilder: kSlideBottomToTopWithSecondary,
|
||||||
|
);
|
||||||
|
Navigator.push(context, route);
|
||||||
|
// Navigator.pushReplacement(context, route);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
22
lib/11/transition.dart
Normal file
22
lib/11/transition.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
RouteTransitionsBuilder kSlideBottomToTopWithSecondary = (
|
||||||
|
BuildContext context,
|
||||||
|
Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation,
|
||||||
|
Widget child,
|
||||||
|
) {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 1.0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: Offset.zero,
|
||||||
|
end: const Offset(0.0, 1.0),
|
||||||
|
).animate(secondaryAnimation),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
13
pubspec.lock
13
pubspec.lock
@@ -102,6 +102,11 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -120,6 +125,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.1.0"
|
version: "10.1.0"
|
||||||
|
intl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.18.1"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
flutter_colorpicker: ^1.0.3
|
flutter_colorpicker: ^1.0.3
|
||||||
# window_manager: ^0.3.7
|
# window_manager: ^0.3.7
|
||||||
adaptive_navigation: ^0.0.4
|
adaptive_navigation: ^0.0.4
|
||||||
@@ -43,8 +45,8 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
toly_menu:
|
# toly_menu:
|
||||||
path: E:\Projects\Flutter\packages\toly_menu
|
# path: E:\Projects\Flutter\packages\toly_menu
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,20 +1,9 @@
|
|||||||
|
import 'package:iroute/10/more_pop_icon.dart';
|
||||||
import 'package:iroute/13/04/app/navigation/router/iroute.dart';
|
import 'package:iroute/13/04/app/navigation/router/iroute.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
String path = '/color/detail/a';
|
bool b = MenuAction.help > MenuAction.about;
|
||||||
// List<String> parts = path.split('/');
|
print(b);
|
||||||
// print(parts);
|
|
||||||
// print(parserPath(path));
|
|
||||||
|
|
||||||
Uri uri = Uri.parse(path);
|
|
||||||
print(uri.fragment);
|
|
||||||
print(uri.pathSegments);
|
|
||||||
|
|
||||||
List<String> parts = uri.pathSegments;
|
|
||||||
|
|
||||||
parts = List.of(parts)..removeLast();
|
|
||||||
String result = parts.join('/');
|
|
||||||
print(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user