7 Commits
app ... master

Author SHA1 Message Date
toly
89eebe3ad8 ext 2024-01-22 08:26:35 +08:00
toly
2a69cb706b fix pushAndRemoveUntil demo 2024-01-11 14:58:25 +08:00
toly
74f9c288ab fix pushAndRemoveUntil demo 2024-01-11 14:55:19 +08:00
toly
72c3cc607d done 2023-12-27 01:06:25 +08:00
toly
1aeab4fa64 1 2023-12-27 00:55:04 +08:00
toly
34d8e6dd75 路由生命周期状态 2023-12-07 08:10:09 +08:00
toly
25b3bc16b2 2023-10-21 10:23:50 +08:00
557 changed files with 4806 additions and 29397 deletions

27
lib/03/01/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'dart:math';
import 'package:flutter/material.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(
appBar: AppBar(
title: Text('添加颜色'),
actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
child: Row(
children: [
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
Container(
margin: EdgeInsets.only(left: 10),
width: 40,
height: 40,
child: Icon(
Icons.sell_outlined,
color: Colors.white,
),
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(8),
),
),
],
),
),
);
}
Random _random = Random();
Color get randomColor {
return Color.fromARGB(
255,
_random.nextInt(256),
_random.nextInt(256),
_random.nextInt(256),
);
}
void _selectColor() {
Navigator.of(context).pop(_color);
}
}

View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'color_add_page.dart';
import '../../../common/components/colors_panel.dart';
import '../../../common/pages/stl_color_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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 = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color));
Navigator.of(context).push(route);
}
void _toAddPage() async {
Route<Color> route = MaterialPageRoute<Color>(builder: (ctx) => const ColorAddPage());
Color? color = await Navigator.of(context).push(route);
if (color != null) {
setState(() {
_colors.add(color);
});
}
}
}

60
lib/03/02/main.dart Normal file
View File

@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'pages/color_add_page.dart';
import '../../common/pages/stl_color_page.dart';
import 'pages/empty_page.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
routes: routeMap,
// initialRoute: '/add_color',
onUnknownRoute: _onUnknownRoute,
onGenerateRoute: _onGenerateRoute,
);
}
/// 路由映射 [字符串 --> 组件构造器]
Map<String, WidgetBuilder> get routeMap => {
'/': (ctx) => const HomePage(),
'/add_color': (ctx) => const ColorAddPage(),
};
/// 根据路由配置 [settings] 创建路由
Route? _onGenerateRoute(RouteSettings settings) {
String? name = settings.name;
Widget? child;
if (name == '/color_detail') {
Color color = settings.arguments as Color;
child = StlColorPage(color: color);
}
if (child != null) {
return MaterialPageRoute(
builder: (ctx) => child!,
settings: settings,
);
}
return null;
}
Route? _onUnknownRoute(RouteSettings settings) {
return MaterialPageRoute(
builder: (ctx) => const EmptyPage(),
settings: settings,
);
}
}

View File

@@ -0,0 +1,67 @@
import 'dart:math';
import 'package:flutter/material.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(
appBar: AppBar(
title: Text('添加颜色'),
actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
child: Row(
children: [
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
Container(
margin: EdgeInsets.only(left: 10),
width: 40,
height: 40,
child: Icon(
Icons.sell_outlined,
color: Colors.white,
),
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(8),
),
),
],
),
),
);
}
Random _random = Random();
Color get randomColor {
return Color.fromARGB(
255,
_random.nextInt(256),
_random.nextInt(256),
_random.nextInt(256),
);
}
void _selectColor() {
Navigator.of(context).pop(_color);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'color_add_page.dart';
import '../../../common/components/colors_panel.dart';
import '../../../common/pages/stl_color_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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('颜色主页 V2')),
floatingActionButton: FloatingActionButton(
onPressed: _toAddPage,
child: const Icon(Icons.add),
),
body: ColorsPanel(
colors: _colors,
onSelect: _selectColor,
),
);
}
void _selectColor(Color color){
Navigator.of(context).pushNamed('/color_detail1',arguments: color);
}
void _toAddPage() async {
dynamic color = await Navigator.of(context).pushNamed('/add_color');
if (color != null) {
setState(() {
_colors.add(color);
});
}
}
}

28
lib/03/03/main.dart Normal file
View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'router1/router1.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
routes: Router1.routeMap,
navigatorKey: Router1.globalNavKey,
onUnknownRoute: Router1.onUnknownRoute,
initialRoute: Router1.initialRoute,
onGenerateRoute: Router1.onGenerateRoute,
);
}
}

View File

@@ -0,0 +1,67 @@
import 'dart:math';
import 'package:flutter/material.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(
appBar: AppBar(
title: Text('添加颜色'),
actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
child: Row(
children: [
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
Container(
margin: EdgeInsets.only(left: 10),
width: 40,
height: 40,
child: Icon(
Icons.sell_outlined,
color: Colors.white,
),
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(8),
),
),
],
),
),
);
}
Random _random = Random();
Color get randomColor {
return Color.fromARGB(
255,
_random.nextInt(256),
_random.nextInt(256),
_random.nextInt(256),
);
}
void _selectColor() {
Navigator.of(context).pop(_color);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import '../router1/router1.dart';
import '../../../common/components/colors_panel.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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('颜色主页 V3')),
floatingActionButton: FloatingActionButton(
onPressed: _toAddPage,
child: const Icon(Icons.add),
),
body: ColorsPanel(
colors: _colors,
onSelect: _selectColor,
),
);
}
void _selectColor(Color color){
Router1.nav.pushNamed(Router1.kColorDetail,arguments: color);
}
void _toAddPage() async {
dynamic color = await Router1.nav.pushNamed(Router1.kAddColor);
if (color != null) {
setState(() {
_colors.add(color);
});
}
}
}

View File

@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import '../../../common/pages/stl_color_page.dart';
import '../pages/color_add_page.dart';
import '../pages/empty_page.dart';
import '../pages/home_page.dart';
class Router1 {
/// 主页面 [HomePage]
static const String kHome = '/';
/// 颜色详情页 [StlColorPage]
static const String kColorDetail = '${kHome}color_detail';
/// 添加颜色页 [ColorAddPage]
static const String kAddColor = '${kHome}add_color';
static String get initialRoute => kHome;
static final GlobalKey<NavigatorState> globalNavKey = GlobalKey();
static NavigatorState get nav => globalNavKey.currentState!;
/// 路由映射 [字符串 --> 组件构造器]
static Map<String, WidgetBuilder> get routeMap => {
kHome: (ctx) => const HomePage(),
kAddColor: (ctx) => const ColorAddPage(),
};
/// 根据路由配置 [settings] 创建路由
static Route? onGenerateRoute(RouteSettings settings) {
String? name = settings.name;
Widget? child;
if (name == kColorDetail) {
Color color = settings.arguments as Color;
child = StlColorPage(color: color);
}
if (child != null) {
return MaterialPageRoute(
builder: (ctx) => child!,
settings: settings,
);
}
return null;
}
static Route? onUnknownRoute(RouteSettings settings) {
return MaterialPageRoute(
builder: (ctx) => const EmptyPage(),
settings: settings,
);
}
}

36
lib/05/01/main.dart Normal file
View File

@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
void main() {
runApp(const OverlayPage());
}
class OverlayPage extends StatelessWidget{
const OverlayPage({super.key});
@override
Widget build(BuildContext context) {
final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage());
return Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: [home],
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const ColoredBox(
color: Colors.white,
child: Align(
child: FlutterLogo(size: 60,),
),
);
}
}

54
lib/05/02/main.dart Normal file
View File

@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
void main() {
runApp(const OverlayPage());
}
class OverlayPage extends StatelessWidget{
const OverlayPage({super.key});
@override
Widget build(BuildContext context) {
final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage());
final OverlayEntry circle = OverlayEntry(builder: (BuildContext context) => const Center(child: Circle()));
return Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: [home,circle],
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const ColoredBox(
color: Colors.white,
child: Align(
child: FlutterLogo(
size: 60,
),
),
);
}
}
class Circle extends StatelessWidget {
const Circle({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 20,
height: 20,
decoration: const BoxDecoration(
color: Colors.redAccent,
shape: BoxShape.circle
),
);
}
}

59
lib/05/03/main.dart Normal file
View File

@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
void main() {
runApp(const OverlayPage());
}
class OverlayPage extends StatelessWidget{
const OverlayPage({super.key});
@override
Widget build(BuildContext context) {
final OverlayEntry home =
OverlayEntry(builder: (BuildContext context) => const HomePage());
final OverlayEntry circle = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: 50,
left: 50,
child: const Circle(),
));
return Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: [home, circle],
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const ColoredBox(
color: Colors.white,
child: Align(
child: FlutterLogo(
size: 60,
),
),
);
}
}
class Circle extends StatelessWidget {
const Circle({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 20,
height: 20,
decoration:
const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle),
);
}
}

77
lib/05/04/main.dart Normal file
View File

@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
void main() {
runApp(const OverlayPage());
}
class OverlayPage extends StatefulWidget {
const OverlayPage({super.key});
@override
State<OverlayPage> createState() => _OverlayPageState();
}
class _OverlayPageState extends State<OverlayPage> {
double _left = 0;
double _top = 0;
@override
Widget build(BuildContext context) {
final OverlayEntry home =
OverlayEntry(builder: (BuildContext context) => const HomePage());
final OverlayEntry circle = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: 50,
left: 50,
child: GestureDetector(
onPanUpdate: _updatePosition,
child: const Circle(),
),
));
return Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: [home, circle],
),
);
}
void _updatePosition(DragUpdateDetails details) {
setState(() {
_top += details.delta.dy;
_left += details.delta.dx;
});
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const ColoredBox(
color: Colors.white,
child: Align(
child: FlutterLogo(
size: 60,
),
),
);
}
}
class Circle extends StatelessWidget {
const Circle({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 20,
height: 20,
decoration:
const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle),
);
}
}

127
lib/05/05/main.dart Normal file
View File

@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
void main() {
runApp(const OverlayPage());
}
class OverlayPage extends StatefulWidget {
const OverlayPage({super.key});
@override
State<OverlayPage> createState() => _OverlayPageState();
}
class _OverlayPageState extends State<OverlayPage> {
@override
Widget build(BuildContext context) {
final OverlayEntry home = OverlayEntry(builder: (BuildContext context) => const HomePage());
return Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: [home],
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
OverlayEntry? entry;
@override
Widget build(BuildContext context) {
return ColoredBox(
color: Colors.white,
child: Align(
child: GestureDetector(
onTap: _toggle,
child: const FlutterLogo(
size: 60,
),
),
),
);
}
void _toggle() {
if(entry==null){
entry = _createPoint();
Overlay.of(context).insert(entry!);
}else{
entry!.remove();
entry = null;
}
}
OverlayEntry _createPoint() {
return OverlayEntry(
builder: (BuildContext context) => Positioned(
width: 20,
height: 20,
left: 20,
top: 20,
child: GestureDetector(child: const Circle()),
),
);
}
}
class ClickShowPage extends StatefulWidget {
const ClickShowPage({super.key});
@override
State<ClickShowPage> createState() => _ClickShowPageState();
}
class _ClickShowPageState extends State<ClickShowPage> {
Offset _position = Offset.zero;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _addPoint,
onTapDown: _onTapDown,
);
}
void _addPoint() {
OverlayEntry entry = _createPoint();
Overlay.of(context).insert(entry);
}
OverlayEntry _createPoint() {
return OverlayEntry(
builder: (BuildContext context) => Positioned(
width: 20,
height: 20,
left: _position.dx - 10,
top: _position.dy - 10,
child: Circle()),
);
}
void _onTapDown(TapDownDetails details) {
_position = details.localPosition;
}
}
class Circle extends StatelessWidget {
const Circle({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 20,
height: 20,
decoration:
const BoxDecoration(color: Colors.redAccent, shape: BoxShape.circle),
);
}
}

27
lib/05/06/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'dart:math';
import 'package:flutter/material.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(
appBar: AppBar(
title: Text('添加颜色'),
actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
child: Row(
children: [
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
Container(
margin: EdgeInsets.only(left: 10),
width: 40,
height: 40,
child: Icon(
Icons.sell_outlined,
color: Colors.white,
),
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(8),
),
),
],
),
),
);
}
Random _random = Random();
Color get randomColor {
return Color.fromARGB(
255,
_random.nextInt(256),
_random.nextInt(256),
_random.nextInt(256),
);
}
void _selectColor() {
Navigator.of(context).pop(_color);
}
}

View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'color_add_page.dart';
import '../../../common/components/colors_panel.dart';
import '../../../common/pages/stl_color_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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 = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color));
Navigator.of(context).push(route);
}
void _toAddPage() async {
Route<Color> route = MaterialPageRoute<Color>(builder: (ctx) => const ColorAddPage());
Color? color = await Navigator.of(context).push(route);
if (color != null) {
setState(() {
_colors.add(color);
});
}
}
}

27
lib/06/01/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'dart:math';
import 'package:flutter/material.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(
appBar: AppBar(
title: Text('添加颜色'),
actions: [IconButton(onPressed: _selectColor, icon: Icon(Icons.check ))],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 20),
child: Row(
children: [
Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)),
Container(
margin: EdgeInsets.only(left: 10),
width: 40,
height: 40,
child: Icon(
Icons.sell_outlined,
color: Colors.white,
),
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(8),
),
),
],
),
),
);
}
Random _random = Random();
Color get randomColor {
return Color.fromARGB(
255,
_random.nextInt(256),
_random.nextInt(256),
_random.nextInt(256),
);
}
void _selectColor() {
Navigator.of(context).pop(_color);
}
}

View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'color_add_page.dart';
import '../../../common/components/colors_panel.dart';
import '../../../common/pages/stl_color_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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 = MaterialPageRoute(builder: (ctx) => StlColorPage(color: color));
Navigator.of(context).push(route);
}
void _toAddPage() async {
Route<Color> route = MaterialPageRoute<Color>(builder: (ctx) => const ColorAddPage());
Color? color = await Navigator.of(context).push(route);
if (color != null) {
setState(() {
_colors.add(color);
});
}
}
}

49
lib/06/02/main.dart Normal file
View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
import 'pages/page_b.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
initialRoute: '/a/b',
onGenerateRoute: _onGenerateRoute,
);
}
Route? _onGenerateRoute(RouteSettings settings) {
String? name = settings.name;
Widget? page ;
if(name=='/'){
page = const HomePage();
}
if(name=='/a'){
page = const PageA();
}
if(name=='/a/b'){
page = const PageB();
}
if(page!=null){
return MaterialPageRoute(builder: (_)=> page!,settings: settings);
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('主页面'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageA(context),
child: const Text('Push A'),
),
),
);
}
void toPageA(BuildContext context){
Navigator.of(context).pushNamed('/a');
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB()));
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'home_page.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('回到主界面'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).popUntil(ModalRoute.withName('/'));
}
}

27
lib/07/01/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
home: const PageA(),
);
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB()));
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'page_c.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('Push C'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageC()));
}
}

View File

@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C'),
backgroundColor: bgColor,
),
body: const Center(
child: Text('到达终点'),
),
);
}
}

2
lib/07/节点介绍.txt Normal file
View File

@@ -0,0 +1,2 @@
01: 分析 push 方法。
A、B、C 三个界面跳转。

27
lib/08/01/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
home: const PageA(),
);
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> const PageB()));
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'page_c.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('Push C'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> const PageC()));
}
}

View File

@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C'),
backgroundColor: bgColor,
),
body: const Center(
child: Text('到达终点'),
),
);
}
}

73
lib/08/02/main.dart Normal file
View File

@@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
import 'pages/page_b.dart';
import 'pages/page_c.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
home: const HomePage(),
onUnknownRoute: _onUnknownRoute,
);
}
Route? _onUnknownRoute(RouteSettings settings) {
String? name = settings.name;
Widget? page ;
if(name=='/a'){
page = const PageA();
}
if(name=='/b'){
page = const PageB();
}
if(name=='/c'){
page = const PageC();
}
if(page!=null){
return MaterialPageRoute(builder: (_)=> page!,settings: settings);
}
return null;
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('主页'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageA(context),
child: const Text('Push A'),
),
),
);
}
void toPageA(BuildContext context){
Navigator.of(context).pushNamed('/a');
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).pushNamed('/b');
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'page_c.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('Push C'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).pushNamed('/c');
}
}

View File

@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import 'page_d.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageD(context),
child: const Text('Push D Remove Until A'),
),
),
);
}
void toPageD(BuildContext context){
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute<void>(builder: (BuildContext context) => const PageD()),
ModalRoute.withName('/a'),
);
}
}

View File

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:iroute/06/02/pages/page_a.dart';
class PageD extends StatelessWidget {
const PageD({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFCCFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('D'),
backgroundColor: bgColor,
),
body: Center(
child: const Text('到达终点'),
),
);
}
}

5
lib/08/节点介绍.txt Normal file
View File

@@ -0,0 +1,5 @@
01: 分析 pushReplacement 方法。
A、B、C 三个界面跳转。
02: 分析 pushAndRemoveUntil 方法。
A、B、C、D 四个界面跳转。

27
lib/09/01/main.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
home: const PageA(),
);
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageB()));
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'page_c.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('Push C'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=> const PageC()));
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C'),
backgroundColor: bgColor,
leading: BackButton(
onPressed: (){
Navigator.of(context).pop();
},
),
),
body: const Center(
child: Text('到达终点'),
),
);
}
}

50
lib/09/02/main.dart Normal file
View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'pages/page_a.dart';
import 'pages/page_b.dart';
import 'pages/page_c.dart';
import 'pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 18,fontWeight: FontWeight.bold)
)
),
onUnknownRoute: _onUnknownRoute,
);
}
Route? _onUnknownRoute(RouteSettings settings) {
String? name = settings.name;
Widget? page ;
if(name=='/'){
page = const HomePage();
}
if(name=='/a'){
page = const PageA();
}
if(name=='/b'){
page = const PageB();
}
if(name=='/c'){
page = const PageC();
}
if(page!=null){
return MaterialPageRoute(builder: (_)=> page!,settings: settings);
}
return null;
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:iroute/06/02/pages/page_a.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFCCFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('起点'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageA(context),
child: const Text('Push A'),
),
),
);
}
void toPageA(BuildContext context){
Navigator.of(context).pushNamed('/a');
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'page_b.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('A'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageB(context),
child: const Text('Push B'),
),
),
);
}
void toPageB(BuildContext context){
Navigator.of(context).pushNamed('/b');
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'page_c.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(title: const Text('B',),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageC(context),
child: const Text('Push C'),
),
),
);
}
void toPageC(BuildContext context){
Navigator.of(context).pushNamed('/c');
}
}

View File

@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CD);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: ()=>toPageD(context),
child: const Text('pop Until A'),
),
),
);
}
void toPageD(BuildContext context){
Navigator.of(context).popUntil(
ModalRoute.withName('/a')
);
}
}

4
lib/09/节点介绍.txt Normal file
View File

@@ -0,0 +1,4 @@
01: 分析 pop 方法。
A、B、C 三个界面跳转。
02: 分析 popUntil 方法。

46
lib/10/app_info.dart Normal file
View 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),),
],
),
),
],
),
);
}
}

View 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),
),
);
},
),
),
),
);
}
}

View 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
View 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
View 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();
}
}

View 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;
}

5
lib/10/节点介绍.txt Normal file
View File

@@ -0,0 +1,5 @@
app_info.dart: 弹出对话框界面
cupertino_context_menu_demo.dart: 弹出 CupertinoContextMenu
dropdown_button_color.dart: 弹出 DropdownButton
more_pop_icon.dart: 弹出 PopupMenuButton
search_anchor_demo.dart: 弹出 SearchAnchor

24
lib/11/color_detail.dart Normal file
View 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),),
),
);
}
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import '../common/components/colors_panel.dart';
import 'package:iroute/components/project/colors_panel.dart'; import 'color_detail.dart';
import 'transition.dart';
class ColorPage extends StatefulWidget { class ColorPage extends StatefulWidget {
const ColorPage({super.key}); const ColorPage({super.key});
@@ -33,49 +34,33 @@ class _ColorPageState extends State<ColorPage> {
Colors.cyanAccent, Colors.cyanAccent,
]; ];
@override
void initState() {
print('======_ColorPageState#initState==============');
super.initState();
}
@override
void dispose() {
print('======_ColorPageState#dispose==============');
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
// appBar: AppBar(title:const Text('颜色主页')), appBar: AppBar(title: const Text('颜色主页')),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: _toAddPage, onPressed: _toAddPage,
child: const Icon(Icons.add), child: const Icon(Icons.add),
), ),
body: Align( body: ColorsPanel(
alignment: Alignment.topCenter, colors: _colors,
child: ColorsPanel( onSelect: _selectColor,
colors: _colors,
onSelect: _selectColor,
),
), ),
); );
} }
void _selectColor(Color color) { void _selectColor(Color color) {
String value = color.value.toRadixString(16); Route route = PageRouteBuilder<void>(
context.push('/color/detail?color=$value'); barrierColor: Colors.white,
// GoRouter.of(context) .pushNamed('colorDetail', queryParameters: {'color': value}); pageBuilder: (_, __, ___) => ColorDetailPage(color:color),
transitionsBuilder: kSlideBottomToTopWithSecondary,
);
Navigator.push(context, route);
// Navigator.push(
// context,
// MaterialPageRoute(builder: (_)=>ColorDetailPage(color:color)));
} }
void _toAddPage() async { void _toAddPage() {
Color? color = await context.push('/color/add');
if (color != null) {
setState(() {
_colors.add(color);
});
}
} }
} }

72
lib/11/main.dart Normal file
View 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
View 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,
),
);
};

1
lib/11/节点介绍.txt Normal file
View File

@@ -0,0 +1 @@
路由第二动画控制器效果演示

11
lib/14/01/main.dart Normal file
View File

@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
import 'pages/app/app.dart';
void main() {
runApp(const App());
}

View File

@@ -1,16 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'navigation/views/app_navigation.dart';
class UnitApp extends StatelessWidget { import 'app_navigation.dart';
const UnitApp({super.key}); import 'app_tool_bar.dart';
class App extends StatelessWidget {
const App({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
fontFamily: "宋体",
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
elevation: 0, elevation: 0,
iconTheme: IconThemeData(color: Colors.black), iconTheme: IconThemeData(color: Colors.black),
@@ -20,8 +19,10 @@ class UnitApp extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
))), ))),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: AppNavigation()); home: const Scaffold(
appBar: AppToolBar(),
body: AppNavigation(),
));
} }
} }

View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import '../page_a.dart';
import '../page_b.dart';
import '../page_c.dart';
import '../home_page.dart';
ValueNotifier<List<String>> router = ValueNotifier(['/']);
class AppNavigation extends StatefulWidget {
const AppNavigation({super.key});
@override
State<AppNavigation> createState() => _AppNavigationState();
}
class _AppNavigationState extends State<AppNavigation> {
@override
void dispose() {
router.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: router,
builder: (_, List<String> value, __) => buildNavigatorByConfig(value),
);
}
final Map<String, Page> _pageMap = const {
'/': MaterialPage(child: HomePage()),
'a': MaterialPage(child: PageA()),
'b': MaterialPage(child: PageB()),
'c': MaterialPage(child: PageC()),
};
Widget buildNavigatorByConfig(List<String> value) {
return Navigator(
onPopPage: _onPopPage,
pages: router.value.map((e) => _pageMap[e]!).toList(),
);
}
bool _onPopPage(Route route, result) {
return route.didPop(result);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'app_navigation.dart';
class AppToolBar extends StatefulWidget implements PreferredSizeWidget{
const AppToolBar({super.key});
@override
State<AppToolBar> createState() => _AppToolBarState();
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}
class _AppToolBarState extends State<AppToolBar> {
TextEditingController _ctrl = TextEditingController();
@override
void initState() {
super.initState();
_changRoute();
router.addListener(_changRoute);
}
@override
void dispose() {
router.removeListener(_changRoute);
_ctrl.dispose();
super.dispose();
}
void _changRoute() {
_ctrl.text=router.value.join(',');
}
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
elevation: 0,
title : TextField(
controller: _ctrl,
onSubmitted: _onSubmitted,
decoration: InputDecoration( //装饰
filled: true, //填充
fillColor: Color(0xffF3F6F9), //填充颜色
constraints: BoxConstraints(maxHeight: 34), //约束信息
contentPadding: EdgeInsets.only(top: -14,left: 10),
border: UnderlineInputBorder( //边线信息
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(6)),
),
hintText: "请输入路由", //提示字
hintStyle: TextStyle(fontSize: 14) //提示字样式
),
),
);
}
void _onSubmitted(String value) {
router.value = value.split(',');
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'app/app_navigation.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFCC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('主页起点'),
backgroundColor: bgColor,
),
body: Center(child: ElevatedButton(
onPressed: () => toPageA(context),
child: const Text('Push A'),
),
));
}
void toPageA(BuildContext context) {
router.value = ['/', 'a'];
}
}

View File

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'app/app_navigation.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('A 界面'),
backgroundColor: bgColor,
leading: BackButton(onPressed: _pop),
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageB(context),
child: const Text('Push B'),
),
));
}
void toPageB(BuildContext context) {
router.value = ['/', 'a', 'b'];
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

View File

@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'app/app_navigation.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('B 界面'),
backgroundColor: bgColor,
leading: BackButton(
onPressed: _pop,
),
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageC(context),
child: const Text('Push C'),
),
));
}
void toPageC(BuildContext context){
router.value = ['/','a','b','c'];
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'app/app_navigation.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C 界面'),
backgroundColor: bgColor,
leading: BackButton(onPressed: _pop),
),
body: Center(
child: Text('到达终点'),
));
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

1
lib/14/节点介绍.txt Normal file
View File

@@ -0,0 +1 @@
01: Navigator#page 的使用测试

14
lib/15/01/main.dart Normal file
View File

@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
import 'pages/app/app.dart';
import 'pages/app/app_router_delegate.dart';
AppRouterDelegate router = AppRouterDelegate();
void main() {
runApp(const App());
}

View File

@@ -1,18 +1,16 @@
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_rail.dart';
class UnitApp extends StatelessWidget {
const UnitApp({super.key}); import '../../main.dart';
import 'app_tool_bar.dart';
class App extends StatelessWidget {
const App({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
fontFamily: "宋体",
scaffoldBackgroundColor: Colors.white,
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
elevation: 0, elevation: 0,
iconTheme: IconThemeData(color: Colors.black), iconTheme: IconThemeData(color: Colors.black),
@@ -22,9 +20,10 @@ class UnitApp extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
))), ))),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: AppNavigation() home: Scaffold(
); appBar: const AppToolBar(),
body: Router(routerDelegate: router),
));
} }
} }

View File

@@ -0,0 +1,92 @@
import 'dart:ffi';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../page_a.dart';
import '../page_b.dart';
import '../page_c.dart';
import '../home_page.dart';
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier{
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()),
};
@override
Future<bool> popRoute() async{
print('=======popRoute=========');
return true;
}
bool _onPopPage(Route route, result) {
return route.didPop(result);
}
@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{
// }
// }

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import '../../main.dart';
class AppToolBar extends StatefulWidget implements PreferredSizeWidget{
const AppToolBar({super.key});
@override
State<AppToolBar> createState() => _AppToolBarState();
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}
class _AppToolBarState extends State<AppToolBar> {
TextEditingController _ctrl = TextEditingController();
@override
void initState() {
super.initState();
_changRoute();
router.addListener(_changRoute);
}
@override
void dispose() {
router.removeListener(_changRoute);
_ctrl.dispose();
super.dispose();
}
void _changRoute() {
_ctrl.text= router.value.join(',');
}
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
elevation: 0,
title : TextField(
controller: _ctrl,
onSubmitted: _onSubmitted,
decoration: InputDecoration( //装饰
filled: true, //填充
fillColor: Color(0xffF3F6F9), //填充颜色
constraints: BoxConstraints(maxHeight: 34), //约束信息
contentPadding: EdgeInsets.only(top: -14,left: 10),
border: UnderlineInputBorder( //边线信息
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(6)),
),
hintText: "请输入路由", //提示字
hintStyle: TextStyle(fontSize: 14) //提示字样式
),
),
);
}
void _onSubmitted(String value) {
router.value = value.split(',');
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import '../main.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFCC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('主页起点'),
backgroundColor: bgColor,
),
body: Center(child: ElevatedButton(
onPressed: () => toPageA(context),
child: const Text('Push A'),
),
));
}
void toPageA(BuildContext context) {
router.value = ['/', 'a'];
}
}

View File

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('A 界面'),
backgroundColor: bgColor,
leading: BackButton(onPressed: _pop),
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageB(context),
child: const Text('Push B'),
),
));
}
void toPageB(BuildContext context) {
router.value = ['/', 'a', 'b'];
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

View File

@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('B 界面'),
backgroundColor: bgColor,
leading: BackButton(onPressed: _pop),
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageC(context),
child: const Text('Push C'),
),
));
}
void toPageC(BuildContext context){
router.value = ['/','a','b','c'];
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C 界面'),
backgroundColor: bgColor,
leading: BackButton(onPressed: _pop),
),
body: Center(
child: Text('到达终点'),
));
}
void _pop() {
router.value = List.of(router.value)..removeLast();
}
}

13
lib/15/02/main.dart Normal file
View File

@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'pages/app/app.dart';
import 'pages/app/app_router_delegate.dart';
AppRouterDelegate router = AppRouterDelegate();
void main() {
runApp(const App());
}

View File

@@ -1,18 +1,15 @@
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_rail.dart';
class UnitApp extends StatelessWidget { import '../../main.dart';
const UnitApp({super.key}); import 'app_tool_bar.dart';
class App extends StatelessWidget {
const App({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
fontFamily: "宋体",
scaffoldBackgroundColor: Colors.white,
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
elevation: 0, elevation: 0,
iconTheme: IconThemeData(color: Colors.black), iconTheme: IconThemeData(color: Colors.black),
@@ -22,9 +19,12 @@ class UnitApp extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
))), ))),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: AppNavigation() home: Scaffold(
); appBar: const AppToolBar(),
body: Router(
routerDelegate: router,
backButtonDispatcher: RootBackButtonDispatcher(),
),
));
} }
} }

View File

@@ -0,0 +1,93 @@
import 'dart:ffi';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../page_a.dart';
import '../page_b.dart';
import '../page_c.dart';
import '../home_page.dart';
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier{
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()),
};
@override
Future<bool> popRoute() async{
print('=======popRoute=========');
return true;
}
bool _onPopPage(Route route, result) {
value = List.of(_value)..removeLast();
return route.didPop(result);
}
@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{
// }
// }

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import '../../main.dart';
class AppToolBar extends StatefulWidget implements PreferredSizeWidget{
const AppToolBar({super.key});
@override
State<AppToolBar> createState() => _AppToolBarState();
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}
class _AppToolBarState extends State<AppToolBar> {
TextEditingController _ctrl = TextEditingController();
@override
void initState() {
super.initState();
_changRoute();
router.addListener(_changRoute);
}
@override
void dispose() {
router.removeListener(_changRoute);
_ctrl.dispose();
super.dispose();
}
void _changRoute() {
_ctrl.text= router.value.join(',');
}
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
elevation: 0,
title : TextField(
controller: _ctrl,
onSubmitted: _onSubmitted,
decoration: InputDecoration( //装饰
filled: true, //填充
fillColor: Color(0xffF3F6F9), //填充颜色
constraints: BoxConstraints(maxHeight: 34), //约束信息
contentPadding: EdgeInsets.only(top: -14,left: 10),
border: UnderlineInputBorder( //边线信息
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(6)),
),
hintText: "请输入路由", //提示字
hintStyle: TextStyle(fontSize: 14) //提示字样式
),
),
);
}
void _onSubmitted(String value) {
router.value = value.split(',');
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import '../main.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFCC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('主页起点'),
backgroundColor: bgColor,
),
body: Center(child: ElevatedButton(
onPressed: () => toPageA(context),
child: const Text('Push A'),
),
));
}
void toPageA(BuildContext context) {
router.value = ['/', 'a'];
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCFFFF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('A 界面'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageB(context),
child: const Text('Push B'),
),
));
}
void toPageB(BuildContext context) {
router.value = ['/', 'a', 'b'];
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffCCE5FF);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('B 界面'),
backgroundColor: bgColor,
),
body: Center(
child: ElevatedButton(
onPressed: () => toPageC(context),
child: const Text('Push C'),
),
));
}
void toPageC(BuildContext context){
router.value = ['/','a','b','c'];
}
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import '../main.dart';
class PageC extends StatelessWidget {
const PageC({super.key});
@override
Widget build(BuildContext context) {
const Color bgColor = Color(0xffFFE6CC);
return Scaffold(
backgroundColor: bgColor,
appBar: AppBar(
title: const Text('C 界面'),
backgroundColor: bgColor,
),
body: Center(
child: Text('到达终点'),
));
}
}

View File

@@ -10,6 +10,7 @@ class UnitApp extends StatelessWidget {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
useMaterial3: false,
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
elevation: 0, elevation: 0,
iconTheme: IconThemeData(color: Colors.black), iconTheme: IconThemeData(color: Colors.black),

16
lib/15/03/main.dart Normal file
View File

@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'app/unit_app.dart';
import 'app/navigation/app_router_delegate.dart';
void main() {
runApp(const UnitApp());
}

View File

@@ -1,5 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:iroute/components/project/colors_panel.dart'; import 'package:iroute/common/components/colors_panel.dart';
import 'package:iroute/common/pages/stl_color_page.dart';
// class HomePage extends StatelessWidget {
// const HomePage({super.key});
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// body: const Center(child: Text('HomePage')));
// }
// }
class ColorPage extends StatefulWidget { class ColorPage extends StatefulWidget {
const ColorPage({super.key}); const ColorPage({super.key});

Some files were not shown because too many files have changed in this diff Show More