diff --git a/assets/data/data.json b/assets/data/data.json deleted file mode 100644 index d966aaa..0000000 --- a/assets/data/data.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"toly", - "age": "25" -} \ No newline at end of file diff --git a/assets/data/widget.json b/assets/data/widget.json index b029ed2..cdf9bc5 100644 --- a/assets/data/widget.json +++ b/assets/data/widget.json @@ -64,7 +64,7 @@ "id": 7, "family": 0, "name": "ImageIcon", - "linkWidget": "7,30,125", + "linkWidget": "6,30,125", "nameCN": "容器", "lever": 1, "info": "用于将一个图片变为纯色的组件。可指定大小、颜色。", @@ -75,7 +75,7 @@ "family": 0, "name": "FadeInImage", "nameCN": "淡入图片", - "linkWidget": "7,30,125", + "linkWidget": "38", "lever": 2, "info": "透明渐变地加载一张图片。可指定占位图片、进退的动画曲线、时间、宽高、fit类型、对齐方式、重复方式等。", "image": "assets/images/widgets/FadeInImage.png" @@ -295,7 +295,7 @@ "family": 0, "name": "IconButton", "nameCN": "图标按钮", - "linkWidget": "", + "linkWidget": "6", "lever": 2, "info": "可点击的图标按钮,可指定图标信息、内边距、大小、颜色等,接收点击事件。", "image": "" @@ -304,6 +304,7 @@ "id": 31, "family": 0, "name": "BackButton", + "nameCN": "返回按钮", "linkWidget": "30", "lever": 1, "info": "一个具有返回功能的IconButton,返回图标不可更改。在iOS和Android中表现不同", @@ -694,7 +695,7 @@ "family": 2, "name": "DecoratedBox", "nameCN": "装饰盒", - "linkWidget": "", + "linkWidget": "1", "lever": 3, "info": "可容纳一个子组件,可将其进行装饰。核心属性为decoration,可设置边线、渐变、阴影、背景图等。", "image": "" @@ -703,7 +704,7 @@ "id": 71, "family": 2, "name": "Offstage", - "nameCN": "装饰盒", + "nameCN": "消失组件", "linkWidget": "10", "lever": 3, "info": "可容纳一个子组件,可更改其的消失与否。offstage属性为true表示隐藏。", @@ -794,7 +795,7 @@ "family": 2, "name": "ConstrainedBox", "nameCN": "约束盒", - "linkWidget": "79,81", + "linkWidget": "1,79,81", "lever": 3, "info": "可容纳一个子组件,通过指定最大、最小宽高,来限定子组件容身区域。", "image": "" @@ -844,7 +845,7 @@ "family": 2, "name": "Align", "nameCN": "对齐组件", - "linkWidget": "86,111,120", + "linkWidget": "1,86,111,120", "lever": 5, "info": "可容纳一个子组件,可以通过alignment让子组件,定位在父组件宽高的任何指定分率出。", "image": "" @@ -1674,7 +1675,7 @@ "family": 0, "name": "Theme", "nameCN": "主题", - "linkWidget": "169", + "linkWidget": "65,169", "lever": 4, "info": "可通过Theme.of获取ThemeData对象。也可以指定主题应用于Theme的后代组件。", "image": "" @@ -1684,7 +1685,7 @@ "family": 0, "name": "CupertinoTheme", "nameCN": "iOS主题", - "linkWidget": "168", + "linkWidget": "156,168", "lever": 3, "info": "可通过CupertinoTheme.of获取CupertinoThemeData对象。也可以指定主题应用于CupertinoTheme的后代组件。", "image": "" diff --git a/assets/data/zero_zone.txt b/assets/data/zero_zone.txt deleted file mode 100755 index 3a3a7ba..0000000 --- a/assets/data/zero_zone.txt +++ /dev/null @@ -1,6 +0,0 @@ -《零境》张风杰特烈 -飘缥兮飞烟浮定, -渺缈兮皓月风清。 -纷纷兮初心复始, -繁繁兮万绪归零。 - 2017.11.7改 \ No newline at end of file diff --git a/assets/fonts/Alibaba-PuHuiTi-Medium.otf b/assets/fonts/Alibaba-PuHuiTi-Medium.otf deleted file mode 100755 index a308250..0000000 Binary files a/assets/fonts/Alibaba-PuHuiTi-Medium.otf and /dev/null differ diff --git a/assets/fonts/BalooBhai2-Regular.ttf b/assets/fonts/BalooBhai2-Regular.ttf new file mode 100644 index 0000000..21a9430 Binary files /dev/null and b/assets/fonts/BalooBhai2-Regular.ttf differ diff --git a/assets/fonts/ComicNeue-Regular.ttf b/assets/fonts/ComicNeue-Regular.ttf new file mode 100644 index 0000000..cbfed15 Binary files /dev/null and b/assets/fonts/ComicNeue-Regular.ttf differ diff --git a/assets/fonts/DancingScript-Regular.ttf b/assets/fonts/DancingScript-Regular.ttf new file mode 100644 index 0000000..f743783 Binary files /dev/null and b/assets/fonts/DancingScript-Regular.ttf differ diff --git a/assets/fonts/Inconsolata-Regular.ttf b/assets/fonts/Inconsolata-Regular.ttf new file mode 100644 index 0000000..18a0708 Binary files /dev/null and b/assets/fonts/Inconsolata-Regular.ttf differ diff --git a/assets/fonts/IndieFlower-Regular.ttf b/assets/fonts/IndieFlower-Regular.ttf new file mode 100644 index 0000000..1070aac Binary files /dev/null and b/assets/fonts/IndieFlower-Regular.ttf differ diff --git a/assets/fonts/Menlo.ttc b/assets/fonts/Menlo.ttc deleted file mode 100644 index daa8b19..0000000 Binary files a/assets/fonts/Menlo.ttc and /dev/null differ diff --git a/assets/fonts/Neucha-Regular.ttf b/assets/fonts/Neucha-Regular.ttf new file mode 100644 index 0000000..a9b9158 Binary files /dev/null and b/assets/fonts/Neucha-Regular.ttf differ diff --git a/assets/iconfont/iconfont.ttf b/assets/iconfont/iconfont.ttf index 959e370..2b1e210 100644 Binary files a/assets/iconfont/iconfont.ttf and b/assets/iconfont/iconfont.ttf differ diff --git a/lib/app/res/cons.dart b/lib/app/res/cons.dart index 447b7a6..08d0b8c 100644 --- a/lib/app/res/cons.dart +++ b/lib/app/res/cons.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; class Cons { static const TABS = [ @@ -11,7 +12,7 @@ class Cons { static const MENU_INFO = ["关于", "帮助", "问题反馈"]; //菜单栏 static const ICONS_MAP = { //底栏图标 - "图鉴": TolyIcon.icon_widgit, "收藏": TolyIcon.icon_star, + "图鉴": TolyIcon.icon_layout, "收藏": TolyIcon.icon_star, // "喜欢": Icons.favorite, "手册": Icons.class_, // "我的": Icons.account_circle, }; @@ -36,5 +37,56 @@ class Cons { 0xFF00F1F1, 0xFFDBD83F ]; - static const tabs = ['Stles', 'Stful', 'Scrow', 'Mcrow', 'Sliver', 'Proxy', 'Other']; //标题列表 + static const tabs = [ + 'Stles', + 'Stful', + 'Scrow', + 'Mcrow', + 'Sliver', + 'Proxy', + 'Other' + ]; //标题列表 + + static const fontFamilySupport = [ + 'local', + 'ComicNeue', + 'IndieFlower', + 'BalooBhai2', + 'Inconsolata', + 'Neucha' + ]; + + static var codeThemeSupport = { + HighlighterStyle.fromColors(HighlighterStyle.gitHub):"GitHub - Power By 张风捷特烈", + HighlighterStyle.fromColors(HighlighterStyle.darkColor):"捷特黑 - Power By 张风捷特烈", + HighlighterStyle.fromColors(HighlighterStyle.lightColor):"捷特白 - Power By 张风捷特烈", + HighlighterStyle.fromColors(HighlighterStyle.zenburn):"zenburn - Power By 张风捷特烈", + HighlighterStyle.fromColors(HighlighterStyle.mf):"mf - Power By MF", + }; + + + static final themeColorSupport = { + Colors.red: "毁灭之红", + Colors.orange: "愤怒之橙", + Colors.yellow: "警告之黄", + Colors.green: "伪装之绿", + Colors.blue: "冷漠之蓝", + Colors.indigo: "无限之靛", + Colors.purple: "神秘之紫", + + MaterialColor(0xff2D2D2D, { + 50: Color(0xFF8A8A8A), + 100: Color(0xFF747474), + 200: Color(0xFF616161), + 300: Color(0xFF484848), + 400: Color(0xFF3D3D3D), + 500: Color(0xff2D2D2D), + 600: Color(0xFF252525), + 700: Color(0xFF141414), + 800: Color(0xFF050505), + 900: Color(0xff000000), + }): "归宿之黑" + }; + } + diff --git a/lib/app/res/node_data.dart b/lib/app/res/node_data.dart index 7300aa6..54c8fec 100644 --- a/lib/app/res/node_data.dart +++ b/lib/app/res/node_data.dart @@ -2,94 +2,110 @@ const nodeData = { "Container": [ { "widgetId": 1, - "name": '可以在区域中放入一个子组件', + "name": '可用于显示一个指定宽高的区域', "priority": 1, - "subtitle": "【padding】 : 内边距 【EdgeInsetsGeometry】\n" - "【margin】: 外边距 【EdgeInsetsGeometry】\n" - "【child】: 子组件 【Widget】", - "code": """class ContainerAlignment extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - alignment: Alignment.bottomRight, - width: 200, - height: 200 * 0.618, - color: Colors.grey.withAlpha(88), - child: Icon( - Icons.android, - color: Colors.green, - ), - ); - } - }""" + "subtitle": "【width】 : 宽 【int】\n" + "【高】: 外边距 【int】\n" + "【color】: 子组件 【Color】", + "code": """class CustomContainer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.topLeft, + width: 200, + height: 200 * 0.618, + color: Colors.red.withAlpha(88), + ); + } +}""" }, { "widgetId": 1, - "name": '可对子组件进行对齐定位', + "name": '可以在区域中放入一个子组件', "priority": 2, - "subtitle": "【alignment】 : 对齐定位 【AlignmentGeometry】", - "code": """class ContainerDecoration extends StatelessWidget { - @override - Widget build(BuildContext context) { - var stops = [0.0, 1 / 6, 2 / 6, 3 / 6, 4 / 6, 5 / 6, 1.0] - return Container( - //容器 - alignment: Alignment.center, - width: 200, - height: 200 * 0.618, - margin: EdgeInsets.all(20), - padding: EdgeInsets.all(20), - decoration: BoxDecoration( - //添加渐变色 - gradient: LinearGradient( - stops: stops, - colors: Cons.rainbow.map((e) => Color(e)).toList()), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(50), - bottomRight: Radius.circular(50)), - boxShadow: [ - BoxShadow( - color: Colors.grey, - offset: Offset(1, 1), - blurRadius: 10, - spreadRadius: 1), - ]), - child: Text( - "Container", - style: TextStyle(fontSize: 20), - ), - ); - } - }""" + "subtitle": "【padding】 : 内边距 【EdgeInsetsGeometry】\n" + "【margin】: 外边距 【EdgeInsetsGeometry】\n" + "【child】: 子组件 【Widget】", + "code": """class ContainerWithChild extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.topLeft, + padding: EdgeInsets.all(20), + margin: EdgeInsets.all(10), + width: 200, + height: 200 * 0.618, + color: Colors.grey.withAlpha(88), + child: Icon(Icons.android), + ); + } +}}""" }, { "widgetId": 1, "name": '可对子组件进行对齐定位', "priority": 3, + "subtitle": "【alignment】 : 对齐定位 【AlignmentGeometry】", + "code": """class ContainerAlignment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.bottomRight, + width: 200, + height: 200 * 0.618, + color: Colors.grey.withAlpha(88), + child: Icon( + Icons.android, + color: Colors.green, + ), + ); + } +}""" + }, + { + "widgetId": 1, + "name": '可对子组件进行装饰', + "priority": 4, "subtitle": "【decoration】 : 装饰 【Decoration】\n 可装饰: 边线、圆弧、颜色、渐变色、阴影、图片等内容", - "code": """class ContainerTransform extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - //容器 - alignment: Alignment.center, - color: Colors.cyanAccent, - width: 150, - height: 150 * 0.618, - transform: Matrix4.skew(-pi / 10, 0), - child: Text( - "Container", - style: TextStyle(fontSize: 20), - ), - ); - } - }""" + "code": """class ContainerDecoration extends StatelessWidget { + @override + Widget build(BuildContext context) { + var stops = [0.0, 1 / 6, 2 / 6, 3 / 6, 4 / 6, 5 / 6, 1.0]; + return Container( + //容器 + alignment: Alignment.center, + width: 200, + height: 200 * 0.618, + margin: EdgeInsets.all(20), + padding: EdgeInsets.all(20), + decoration: BoxDecoration( + //添加渐变色 + gradient: LinearGradient( + stops: stops, + colors: Cons.rainbow.map((e) => Color(e)).toList()), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(50), + bottomRight: Radius.circular(50)), + boxShadow: [ + BoxShadow( + color: Colors.grey, + offset: Offset(1, 1), + blurRadius: 10, + spreadRadius: 1), + ]), + child: Text( + "Container", + style: TextStyle(fontSize: 20), + ), + ); + } +}""" }, { "widgetId": 1, "name": 'Container还具有变换性', - "priority": 4, + "priority": 5, "subtitle": "【transform】 : 变换矩阵 【Matrix4】\n 基于Matrix4的矩阵变换,变换详情见线性代数", "code": """class ContainerTransform extends StatelessWidget { @override @@ -112,7 +128,7 @@ const nodeData = { { "widgetId": 1, "name": 'Container的约束性', - "priority": 5, + "priority": 6, "subtitle": "【constraints】 : 约束 【BoxConstraints】\n 会约束该区域的尺寸,不会小于指定的最小宽高,也不会大于指定的最大宽高。", "code": """class ContainerConstraints extends StatelessWidget { @@ -147,7 +163,7 @@ const nodeData = { @override Widget build(BuildContext context) { var style = TextStyle( - color: Colors.red, + color: Colors.blue, fontSize: 20, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, @@ -213,7 +229,7 @@ const nodeData = { decorationStyle: TextDecorationStyle.wavy, decorationColor: Colors.blue, fontStyle: FontStyle.italic, - fontFamily: "Menlo", + fontFamily: "DancingScript", letterSpacing: 10), ); } @@ -5891,7 +5907,7 @@ class _CustomUnConstrainedBoxState extends State { ], "FractionallySizedBox": [ { - "widgetId": 81, + "widgetId": 82, "name": 'FractionallySizedBox基本使用', "priority": 1, "subtitle": "【child】 : 孩子组件 【Widget】\n" @@ -6597,7 +6613,7 @@ class _CustomSizeTransitionState extends State ], "PositionedTransition": [ { - "widgetId": 92, + "widgetId": 93, "name": 'PositionedTransition基本使用', "priority": 1, "subtitle": "【child】 : 孩子组件 【Widget】\n" @@ -6662,194 +6678,262 @@ class _CustomPositionedTransitionState extends State "Flex": [ { "widgetId": 94, - "name": 'Flex基本使用', + "name": 'Flex的排布方向', "priority": 1, - "subtitle": "【children】 : 组件列表 【List】\n" - "【direction】 : 方向 【Axis】\n" - "【mainAxisAlignment】 : 主轴对齐 【MainAxisAlignment】\n" - "【crossAxisAlignment】 : 交叉轴对齐 【CrossAxisAlignment】\n" - "【textBaseline】 : 文字基线 【TextBaseline】\n" - "【verticalDirection】 : 竖直方向 【VerticalDirection】\n" - "【mainAxisSize】 : 主轴尺寸 【MainAxisSize】", - "code": """class CustomFlex extends StatefulWidget { - @override - _CustomFlexState createState() => _CustomFlexState(); -} + "subtitle": + "【children】 : 组件列表 【List】\n" + "【direction】 : 方向 【Axis】", + "code": """class DirectionFlex extends StatelessWidget { -class _CustomFlexState extends State { - final redBox = Container( + final redBox= Container( color: Colors.red, - height: 50, - width: 50, - ); - final blueBox = Container( - color: Colors.blue, - width: 60, - height: 60, - ); - final yellowBox = Container( - color: Colors.yellow, - height: 10, - width: 10, - ); - final greenBox = Container( - color: Colors.green, height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, width: 20, ); - var _direction = Axis.horizontal; - var _mainAxisAlignment = MainAxisAlignment.start; - var _crossAxisAlignment = CrossAxisAlignment.center; - var _verticalDirection = VerticalDirection.up; @override Widget build(BuildContext context) { - return Column( - children: [ - _buildDirectionSelector(), - _buildMainAxisAlignmentSelector(), - _buildCrossAxisAlignmentSelector(), - _buildVerticalDirectionSelector(), - Container( - width: 300, - height: 300 * 0.618, - color: Colors.grey.withAlpha(33), - child: Flex( - textBaseline: TextBaseline.alphabetic, - direction: _direction, - mainAxisAlignment: _mainAxisAlignment, - crossAxisAlignment: _crossAxisAlignment, - verticalDirection: _verticalDirection, - children: [redBox, blueBox, yellowBox, greenBox], - ), - ), - ], - ); + return Wrap( + children: Axis.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 100, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); } - Widget _buildDirectionSelector() { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "direction", - style: TextStyle( - fontSize: 16, color: Colors.blue, fontWeight: FontWeight.bold), - ), - DropdownButton( - elevation: 1, - underline: Container(), - value: _direction, - items: Axis.values - .map((e) => DropdownMenuItem( - value: e, - child: Text(e.toString()), - )) - .toList(), - onChanged: (e) { - setState(() { - _direction = e; - }); - }), - ], - ), - ); + _buildItem(mode) => Flex( + direction: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +}""" + }, + { + "widgetId": 94, + "name": 'Flex主轴对齐方式', + "priority": 2, + "subtitle": + "【mainAxisAlignment】 : 主轴对齐 【MainAxisAlignment】", + "code": """class MainAxisAlignmentFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: MainAxisAlignment.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 100, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); } - Widget _buildMainAxisAlignmentSelector() { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "mainAxisAlignment", - style: TextStyle( - fontSize: 16, color: Colors.blue, fontWeight: FontWeight.bold), - ), - DropdownButton( - elevation: 1, - underline: Container(), - value: _mainAxisAlignment, - items: MainAxisAlignment.values - .map((e) => DropdownMenuItem( - value: e, - child: Text(e.toString().split('.')[1]), - )) - .toList(), - onChanged: (e) { - setState(() { - _mainAxisAlignment = e; - }); - }), - ], - ), - ); + _buildItem(mode) => Flex( + direction: Axis.horizontal, + mainAxisAlignment: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +}""" + }, + { + "widgetId": 94, + "name": 'Flex交叉轴对齐方式', + "priority": 3, + "subtitle": + "【crossAxisAlignment】 : 交叉轴对齐 【CrossAxisAlignment】", + "code": """class CrossAxisAlignmentFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: CrossAxisAlignment.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); } - Widget _buildCrossAxisAlignmentSelector() { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "crossAxisAlignment", - style: TextStyle( - fontSize: 16, color: Colors.blue, fontWeight: FontWeight.bold), - ), - DropdownButton( - elevation: 1, - underline: Container(), - value: _crossAxisAlignment, - items: CrossAxisAlignment.values - .map((e) => DropdownMenuItem( - value: e, - child: Text(e.toString().split('.')[1]), - )) - .toList(), - onChanged: (e) { - setState(() { - _crossAxisAlignment = e; - }); - }), - ], - ), - ); + _buildItem(mode) => Flex( + direction: Axis.horizontal, + crossAxisAlignment: mode, + textBaseline: TextBaseline.alphabetic, + children: [ + blueBox, redBox, greenBox + ], + ); +}""" + }, + { + "widgetId": 94, + "name": 'Flex垂直方向顺序', + "priority": 4, + "subtitle": + "【verticalDirection】 : 垂直方向顺序 【VerticalDirection】", + "code": """class VerticalDirectionFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: VerticalDirection.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); } - Widget _buildVerticalDirectionSelector() { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "MainAxisSize", - style: TextStyle( - fontSize: 16, color: Colors.blue, fontWeight: FontWeight.bold), - ), - DropdownButton( - elevation: 1, - underline: Container(), - value: _verticalDirection, - items: VerticalDirection.values - .map((e) => DropdownMenuItem( - value: e, - child: Text(e.toString().split('.')[1]), - )) - .toList(), - onChanged: (e) { - setState(() { - _verticalDirection = e; - }); - }), - ], - ), - ); + _buildItem(mode) => Flex( + direction: Axis.vertical, + verticalDirection: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +}""" + }, + { + "widgetId": 94, + "name": 'Flex水平方向顺序', + "priority": 5, + "subtitle": + "【textDirection】 : 水平方向顺序 【TextDirection】", + "code": """class TextDirectionFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: TextDirection.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); } + + _buildItem(mode) => Flex( + direction: Axis.horizontal, + textDirection: mode, + children: [ + blueBox, redBox, greenBox + ], + ); }""" }, ], @@ -6898,7 +6982,7 @@ class _CustomFlexState extends State { ], "Column": [ { - "widgetId": 95, + "widgetId": 96, "name": 'Column基本使用', "priority": 1, "subtitle": "【children】 : 组件列表 【List】\n" @@ -8749,7 +8833,7 @@ class _CustomDecoratedBoxTransitionState ], "DefaultTextStyleTransition": [ { - "widgetId": 113, + "widgetId": 114, "name": 'DefaultTextStyleTransition基本使用', "priority": 1, "subtitle": "【child】 : 孩子组件 【Widget】\n" @@ -10081,7 +10165,7 @@ class DeleteDialog extends StatelessWidget { ], "CupertinoAlertDialog": [ { - "widgetId": 130, + "widgetId": 129, "name": 'CupertinoAlertDialog基本使用', "priority": 1, "subtitle": "【title】 : 顶部组件 【Widget】\n" @@ -12910,7 +12994,8 @@ class BezierPainter extends CustomPainter { "widgetId": 168, "name": '文字样式-ThemeData#TextTheme', "priority": 1, - "subtitle": "", + "subtitle": + "后代组件可以通过ThemeData.of获取主题的数据进行使用。", "code": """class TextThemeDemo extends StatelessWidget { @override Widget build(BuildContext context) { @@ -12965,30 +13050,50 @@ class BezierPainter extends CustomPainter { }, { "widgetId": 168, - "name": 'ThemeData的toString', + "name": 'Theme的用法', "priority": 2, - "subtitle": "", + "subtitle": + "使用Theme,可以指定非常多的属性作为主题,这些属性将应用于所有的后代组件,如指定字体、滑块、卡片、文字、分割线、按钮等属性。注意如果需要使用主题,不能在当前的context中获取。", "code": """class CustomTheme extends StatelessWidget { @override Widget build(BuildContext context) { - var queryData = Theme.of(context); - return Container( - child: Text(queryData.toString(), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.blue, - )), - ); + return Theme( + data: ThemeData( + cardTheme: CardTheme(color: Colors.red, elevation: 4), + dividerTheme: DividerThemeData( + color: Colors.blue, + thickness: 2 + ), + sliderTheme: SliderThemeData( + thumbColor: Colors.red, + activeTrackColor: Colors.green, + inactiveTrackColor: Colors.grey, + )), + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Card( + child: Container( + width: 50, + height: 50, + color: Colors.transparent, + ), + ), + Container( + width: 150, + child: Slider(value: 0.8, onChanged: (v) => {})), + Container( width: 150,child: Divider()) + ])); } }""" }, ], "CupertinoTheme": [ { - "widgetId": 168, + "widgetId": 169, "name": '文字样式-TextTheme', "priority": 1, - "subtitle": "", + "subtitle": "后代组件可以通过CupertinoTheme.of获取主题的数据进行使用。", "code": """class TextCupertinoTheme extends StatelessWidget { @override Widget build(BuildContext context) { @@ -13037,21 +13142,43 @@ class BezierPainter extends CustomPainter { }""" }, { - "widgetId": 168, - "name": 'CupertinoThemeData的toString', + "widgetId": 169, + "name": 'CupertinoThemeData的使用', "priority": 2, - "subtitle": "", + "subtitle": + "和Theme一样可以通过指定的属性,让它们在后代中共享,不过属性较少。注意如果需要使用主题,不能在当前的context中获取。", "code": """class CustomCupertinoTheme extends StatelessWidget { @override Widget build(BuildContext context) { - var queryData = CupertinoTheme.of(context); - return Container( - child: Text(queryData.toString(), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.blue, - )), - ); + return CupertinoTheme( + data: CupertinoThemeData( + primaryColor: Colors.blue, + primaryContrastingColor: Colors.green + ), + child: _ChildUseTheme()); + } +} + +class _ChildUseTheme extends StatelessWidget { + const _ChildUseTheme({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Container( + width: 50, + height: 50, + color: CupertinoTheme.of(context).primaryContrastingColor, + ), + Container( + width: 150, + child: Slider(value: 0.8, onChanged: (v) => {})), + Container( width: 150,child: Divider(color:CupertinoTheme.of(context).primaryContrastingColor,thickness: 1,)) + ]); } }""" }, @@ -14695,8 +14822,8 @@ class _SliverAppBarDemoState extends State { ], "SliverFillViewport": [ { - "widgetId": 186, - "name": 'SliverFixedExtentList基本使用', + "widgetId": 187, + "name": 'SliverFillViewport基本使用', "priority": 1, "subtitle": "【viewportFraction】 : 视口分率 【double】\n" "【delegate】 : 孩子代理 【SliverChildDelegate】", diff --git a/lib/app/res/sp.dart b/lib/app/res/sp.dart new file mode 100644 index 0000000..b5aeb7d --- /dev/null +++ b/lib/app/res/sp.dart @@ -0,0 +1,13 @@ +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +class SP{ + + static const themeColorIndex = 'theme_color_index'; + static const showBackground = 'show_background'; + static const fontFamily = 'font_family'; + static const codeStyleIndex = 'code_style'; + static const itemStyleIndex = 'item_style_index'; + +} \ No newline at end of file diff --git a/lib/app/router.dart b/lib/app/router.dart index d1e9e8a..b8688c9 100644 --- a/lib/app/router.dart +++ b/lib/app/router.dart @@ -1,13 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:flutter_unit/views/pages/setting/code_style_setting.dart'; +import 'package:flutter_unit/views/pages/setting/font_setting.dart'; +import 'package:flutter_unit/views/pages/setting/item_style_setting.dart'; +import 'package:flutter_unit/views/pages/setting/theme_color_setting.dart'; +import 'package:flutter_unit/views/pages/unit/attr_unit_page.dart'; +import 'package:flutter_unit/views/pages/unit/bug_unit_page.dart'; +import 'package:flutter_unit/views/pages/collect_page.dart'; import 'package:flutter_unit/views/pages/detail/widget_detail_page.dart'; +import 'package:flutter_unit/views/pages/unit/layout_unit_page.dart'; +import 'package:flutter_unit/views/pages/unit/paint_unit_page.dart'; import 'package:flutter_unit/views/pages/serach_page.dart'; +import 'package:flutter_unit/views/pages/setting/setting_page.dart'; import 'package:flutter_unit/views/pages/unit_navigation.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/Banner.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/Card.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/Container.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/FlutterLogo.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/Icon.dart'; -import 'package:flutter_unit/views/widgets/StatelessWidget/Text.dart'; import 'router_utils.dart'; @@ -18,6 +22,18 @@ class Router { static const String search = 'search'; static const String nav = 'nav'; static const String widget_detail = 'WidgetDetail'; + static const String collect = 'CollectPage'; + + static const String setting = 'SettingPage'; + static const String font_setting = 'FountSettingPage'; + static const String theme_color_setting = 'ThemeColorSettingPage'; + static const String code_style_setting = 'CodeStyleSettingPage'; + static const String item_style_setting = 'ItemStyleSettingPage'; + + static const String attr = 'AttrUnitPage'; + static const String bug = 'BugUnitPage'; + static const String paint = 'PaintUnitPage'; + static const String layout = 'LayoutUnitPage'; static Route generateRoute(RouteSettings settings) { switch (settings.name) { @@ -26,9 +42,31 @@ class Router { return Right2LeftRouter(child: WidgetDetailPage()); case search: return Right2LeftRouter(child: SearchPage()); + case collect: + return Right2LeftRouter(child: CollectPage()); case nav: return NoAnimRouter(child: UnitNavigation()); + case setting: + return Right2LeftRouter(child: SettingPage()); + case font_setting: + return Right2LeftRouter(child: FontSettingPage()); + case theme_color_setting: + return Right2LeftRouter(child: ThemeColorSettingPage()); + case code_style_setting: + return Right2LeftRouter(child: CodeStyleSettingPage()); + case item_style_setting: + return Right2LeftRouter(child: ItemStyleSettingPage()); + + case attr: + return Right2LeftRouter(child: AttrUnitPage()); + case bug: + return Right2LeftRouter(child: BugUnitPage()); + case paint: + return Right2LeftRouter(child: PaintUnitPage()); + case layout: + return Right2LeftRouter(child: LayoutUnitPage()); + default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/app/style/TolyIcon.dart b/lib/app/style/TolyIcon.dart index 1467f0b..5909c5e 100644 --- a/lib/app/style/TolyIcon.dart +++ b/lib/app/style/TolyIcon.dart @@ -4,8 +4,16 @@ import 'package:flutter/widgets.dart'; class TolyIcon { TolyIcon._(); +static const IconData icon_background = const IconData( 0xe60a, fontFamily: "TolyIcon"); +static const IconData icon_code = const IconData( 0xe70b, fontFamily: "TolyIcon"); +static const IconData icon_item = const IconData( 0xe66f, fontFamily: "TolyIcon"); +static const IconData icon_kafei = const IconData( 0xe6aa, fontFamily: "TolyIcon"); +static const IconData icon_tag = const IconData( 0xe6e7, fontFamily: "TolyIcon"); +static const IconData icon_them = const IconData( 0xe6c2, fontFamily: "TolyIcon"); +static const IconData icon_bug = const IconData( 0xe7af, fontFamily: "TolyIcon"); +static const IconData icon_layout = const IconData( 0xe631, fontFamily: "TolyIcon"); +static const IconData icon_sound = const IconData( 0xe606, fontFamily: "TolyIcon"); static const IconData icon_search = const IconData( 0xe604, fontFamily: "TolyIcon"); -static const IconData icon_widgit = const IconData( 0xe758, fontFamily: "TolyIcon"); static const IconData icon_star_ok = const IconData( 0xe6ae, fontFamily: "TolyIcon"); static const IconData icon_star = const IconData( 0xe609, fontFamily: "TolyIcon"); static const IconData icon_star_add = const IconData( 0xe68e, fontFamily: "TolyIcon"); diff --git a/lib/blocs/collect/collect_bloc.dart b/lib/blocs/collect/collect_bloc.dart new file mode 100644 index 0000000..c9e53fd --- /dev/null +++ b/lib/blocs/collect/collect_bloc.dart @@ -0,0 +1,38 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; +import 'package:flutter_unit/repositorys/widget_repository.dart'; + +import 'collect_event.dart'; +import 'collect_state.dart'; + +/// create by 张风捷特烈 on 2020-04-07 +/// contact me by email 1981462002@qq.com +/// 说明: + + + +class CollectBloc extends Bloc { + final WidgetRepository repository; + + CollectBloc({@required this.repository}); + + @override + CollectState get initialState => CollectState(collect: false,widgets: []); //初始状态 + + @override + Stream mapEventToState( + CollectEvent event, + ) async* { + if (event is ToggleCollectEvent) { + await repository.toggleCollect(event.id); + final widgets = await repository.loadCollectWidgets(); + yield CollectState(collect: !state.collect,widgets: widgets); + } + if( event is EventSetCollectData){ + final widgets = await repository.loadCollectWidgets(); + yield CollectState(collect: state.collect,widgets: widgets); + } + } +} diff --git a/lib/blocs/collect/collect_event.dart b/lib/blocs/collect/collect_event.dart new file mode 100644 index 0000000..bf91149 --- /dev/null +++ b/lib/blocs/collect/collect_event.dart @@ -0,0 +1,43 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter_unit/model/widget_model.dart'; + +/// create by 张风捷特烈 on 2020-04-09 +/// contact me by email 1981462002@qq.com +/// 说明: + + +abstract class CollectEvent extends Equatable {} + + +//class EventSetCollect extends CollectEvent { +// final bool collect; +// +// EventSetCollect({this.collect}); +// +// @override +// // TODO: implement props +// List get props => [collect]; +//} + +class EventSetCollectData extends CollectEvent { + List get props => []; +} + + +class ToggleCollectEvent extends CollectEvent { + final int id; + final bool isCollect; + + ToggleCollectEvent({this.id,this.isCollect}); + + @override + // TODO: implement props + List get props => [id]; +} + +class LoadCollectEvent extends CollectEvent{ + @override + List get props => []; + +} + diff --git a/lib/blocs/collect/collect_state.dart b/lib/blocs/collect/collect_state.dart new file mode 100644 index 0000000..ccb4aa7 --- /dev/null +++ b/lib/blocs/collect/collect_state.dart @@ -0,0 +1,17 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter_unit/model/widget_model.dart'; + +/// create by 张风捷特烈 on 2020-04-09 +/// contact me by email 1981462002@qq.com +/// 说明: + +class CollectState extends Equatable { + final bool collect; + final List widgets; + + CollectState({this.collect,this.widgets}); + + @override + // TODO: implement props + List get props => [collect,widgets]; +} diff --git a/lib/blocs/detail/detail_bloc.dart b/lib/blocs/detail/detail_bloc.dart index a6da2af..cbbc18b 100644 --- a/lib/blocs/detail/detail_bloc.dart +++ b/lib/blocs/detail/detail_bloc.dart @@ -20,7 +20,7 @@ class DetailBloc extends Bloc { @override Stream mapEventToState(DetailEvent event) async* { - if (event is ToWidgetDetail) { + if (event is FetchWidgetDetail) { yield* _mapLoadWidgetToState(event.widgetModel); } } @@ -29,8 +29,9 @@ class DetailBloc extends Bloc { WidgetModel widgetModel) async* { try { final nodes = await this.repository.loadNode(widgetModel); + final links = await this.repository.loadWidget(widgetModel.links); yield DetailWithData( - widgetModel: widgetModel, nodes: nodes); + widgetModel: widgetModel, nodes: nodes,links: links); } catch (_) { yield DetailFailed(); } diff --git a/lib/blocs/detail/detail_event.dart b/lib/blocs/detail/detail_event.dart index 6658c0b..01d6184 100644 --- a/lib/blocs/detail/detail_event.dart +++ b/lib/blocs/detail/detail_event.dart @@ -13,10 +13,10 @@ abstract class DetailEvent extends Equatable { } -class ToWidgetDetail extends DetailEvent { +class FetchWidgetDetail extends DetailEvent { final WidgetModel widgetModel; - const ToWidgetDetail(this.widgetModel); + const FetchWidgetDetail(this.widgetModel); @override List get props => [widgetModel]; diff --git a/lib/blocs/detail/detail_state.dart b/lib/blocs/detail/detail_state.dart index 521be25..9711255 100644 --- a/lib/blocs/detail/detail_state.dart +++ b/lib/blocs/detail/detail_state.dart @@ -17,9 +17,10 @@ abstract class DetailState extends Equatable { class DetailWithData extends DetailState { final WidgetModel widgetModel; + final List links; final List nodes; - const DetailWithData({this.widgetModel, this.nodes}); + const DetailWithData({this.widgetModel, this.nodes,this.links}); @override List get props => [widgetModel,nodes]; diff --git a/lib/blocs/global/global_bloc.dart b/lib/blocs/global/global_bloc.dart index 55c5450..43c4fdb 100644 --- a/lib/blocs/global/global_bloc.dart +++ b/lib/blocs/global/global_bloc.dart @@ -3,77 +3,88 @@ import 'dart:math'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/app/res/sp.dart'; import 'package:flutter_unit/app/utils/color_utils.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import 'global_event.dart'; +import 'global_state.dart'; /// create by 张风捷特烈 on 2020-03-22 /// contact me by email 1981462002@qq.com /// 说明: 全局信息的bloc -class GlobalState extends Equatable { - final double height; - final Color color; - - const GlobalState({this.height, this.color}); - - @override - List get props => [height,color]; - - GlobalState copyWith({ - Color color, - double height, - }) => - GlobalState( - color: color ?? this.color, - height: height ?? this.height, - ); - - @override - String toString() { - return 'GlobalState{height: $height, color: $color}'; - } -} - -abstract class GlobalEvent extends Equatable { - const GlobalEvent(); - - @override - List get props => []; -} - -class EventSwitchColor extends GlobalEvent { - final Color color; - - const EventSwitchColor(this.color); - - @override - List get props => [color]; -} - -class UpdateAppBarHeight extends GlobalEvent { - final double height; - - const UpdateAppBarHeight(this.height); - - @override - List get props => [height]; -} - class GlobalBloc extends Bloc { @override - GlobalState get initialState => - GlobalState(color: Colors.blue, height: kToolbarHeight * 2 - 20); + GlobalState get initialState => GlobalState(); + + SharedPreferences _sp; + + Future get sp async { + _sp = _sp ?? await SharedPreferences.getInstance(); + return _sp; + } @override Stream mapEventToState(GlobalEvent event) async* { - if (event is EventSwitchColor) { - yield* _mapLoadWidgetToState(event.color); + if (event is EventInitApp) { + yield* _initGlobalState(); + } + if (event is EventSwitchHomeColor) { + yield state.copyWith(color: event.color); } if (event is UpdateAppBarHeight) { yield state.copyWith(height: event.height); } + + if (event is EventSwitchFontFamily) { + var familyIndex = Cons.fontFamilySupport.indexOf(event.family); + await sp + ..setInt(SP.fontFamily, familyIndex); //固化数据 + yield state.copyWith(fontFamily: event.family); + } + + if (event is EventSwitchThemeColor) { + var themeIndex = + Cons.themeColorSupport.keys.toList().indexOf(event.color); + await sp + ..setInt(SP.themeColorIndex, themeIndex); //固化数据 + yield state.copyWith(themeColor: event.color); + } + + if (event is EventSwitchShowBg) { + await sp + ..setBool(SP.showBackground, event.show); //固化数据 + yield state.copyWith(showBackGround: event.show); + } + + if (event is EventSwitchCoderTheme) { + await sp..setInt(SP.themeColorIndex, event.codeStyleIndex); //固化数据 + yield state.copyWith(codeStyleIndex: event.codeStyleIndex); + } + if (event is EventChangeItemStyle) { + await sp..setInt(SP.itemStyleIndex, event.index); //固化数据 + yield state.copyWith(itemStyleIndex: event.index); + } } - Stream _mapLoadWidgetToState(Color color) async* { - yield state.copyWith(color: color); + // 初始化 App 固化的配置数据 + Stream _initGlobalState() async* { + var prefs = await sp; + var showBg = prefs.getBool(SP.showBackground) ?? true; + var themeIndex = prefs.getInt(SP.themeColorIndex) ?? 4; + var fontIndex = prefs.getInt(SP.fontFamily) ?? 1; + var codeIndex = prefs.getInt(SP.codeStyleIndex) ?? 0; + var itemStyleIndex = prefs.getInt(SP.itemStyleIndex) ?? 0; + + yield GlobalState( + showBackGround: showBg, + themeColor: Cons.themeColorSupport.keys.toList()[themeIndex], + fontFamily: Cons.fontFamilySupport[fontIndex], + height: kToolbarHeight * 2 - 20, + color: Color(Cons.tabColors[0]), + itemStyleIndex: itemStyleIndex, + codeStyleIndex: codeIndex); } } diff --git a/lib/blocs/global/global_event.dart b/lib/blocs/global/global_event.dart new file mode 100644 index 0000000..c476177 --- /dev/null +++ b/lib/blocs/global/global_event.dart @@ -0,0 +1,82 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; + +abstract class GlobalEvent extends Equatable { + const GlobalEvent(); + + @override + List get props => []; +} + + +class EventInitApp extends GlobalEvent { + const EventInitApp(); + @override + List get props => []; +} + +class EventSwitchHomeColor extends GlobalEvent { + final Color color; + + const EventSwitchHomeColor(this.color); + + @override + List get props => [color]; +} + + +class EventSwitchFontFamily extends GlobalEvent { + final String family; + const EventSwitchFontFamily(this.family); + + @override + List get props => [family]; +} + + +class EventSwitchThemeColor extends GlobalEvent { + final MaterialColor color; + + const EventSwitchThemeColor(this.color); + + @override + List get props => [color]; +} + +class EventSwitchCoderTheme extends GlobalEvent { + final int codeStyleIndex; + + const EventSwitchCoderTheme(this.codeStyleIndex); + + @override + List get props => [codeStyleIndex]; +} + +class EventSwitchShowBg extends GlobalEvent { + final bool show; + + const EventSwitchShowBg(this.show); + + @override + List get props => [show]; +} + +class EventChangeItemStyle extends GlobalEvent { + final int index; + + const EventChangeItemStyle(this.index); + + @override + List get props => [index]; +} + +class UpdateAppBarHeight extends GlobalEvent { + final double height; + + const UpdateAppBarHeight(this.height); + + @override + List get props => [height]; +} \ No newline at end of file diff --git a/lib/blocs/global/global_state.dart b/lib/blocs/global/global_state.dart new file mode 100644 index 0000000..614d268 --- /dev/null +++ b/lib/blocs/global/global_state.dart @@ -0,0 +1,53 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; + +class GlobalState extends Equatable { + final double height; + final Color color; + final String fontFamily; + final MaterialColor themeColor; + final bool showBackGround; + final int codeStyleIndex; + final int itemStyleIndex; + + const GlobalState({ + this.height, + this.color, + this.fontFamily = 'ComicNeue', + this.themeColor = Colors.blue, + this.showBackGround = true, + this.codeStyleIndex, + this.itemStyleIndex, + }); + + @override + List get props => + [height, color, fontFamily, themeColor, showBackGround, codeStyleIndex,itemStyleIndex]; + + GlobalState copyWith({ + Color color, + double height, + String fontFamily, + MaterialColor themeColor, + bool showBackGround, + int codeStyleIndex, + int itemStyleIndex, + }) => + GlobalState( + color: color ?? this.color, + height: height ?? this.height, + fontFamily: fontFamily ?? this.fontFamily, + themeColor: themeColor ?? this.themeColor, + showBackGround: showBackGround ?? this.showBackGround, + codeStyleIndex: codeStyleIndex ?? this.codeStyleIndex, + itemStyleIndex: codeStyleIndex ?? this.itemStyleIndex, + ); + + @override + String toString() { + return 'GlobalState{height: $height, color: $color, fontFamily: $fontFamily, themeColor: $themeColor, showBackGround: $showBackGround, codeStyleIndex: $codeStyleIndex, itemStyleIndex: $itemStyleIndex}'; + } + + +} diff --git a/lib/blocs/search/search_bloc.dart b/lib/blocs/search/search_bloc.dart index f373588..f57f45f 100644 --- a/lib/blocs/search/search_bloc.dart +++ b/lib/blocs/search/search_bloc.dart @@ -1,12 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_unit/repositorys/widget_repository.dart'; + import 'search_event.dart'; import 'search_state.dart'; import 'package:bloc/bloc.dart'; import 'package:rxdart/rxdart.dart'; class SearchBloc extends Bloc { + final WidgetRepository repository; + SearchBloc({@required this.repository}); @override SearchState get initialState => SearchStateNoSearch();//初始状态 @@ -23,18 +28,17 @@ class SearchBloc extends Bloc { @override Stream mapEventToState(SearchEvent event,) async* { - if (event is EventTextChanged) { - print(event.arg); - if (event.arg.isEmpty) { + if (event.args.name.isEmpty&&event.args.stars.every((e)=>e==-1)) { yield SearchStateNoSearch(); } else { yield SearchStateLoading(); try { -// final results = await GithubApi.search(event.arg); -// if(results.items.isEmpty) yield SearchStateEmpty(); -// yield SearchStateSuccess(results); + final results = await repository.searchWidgets(event.args); + yield results.length==0?SearchStateEmpty():SearchStateSuccess(results); + print('mapEventToState'); } catch (error) { + print(error); yield SearchStateError(); } } diff --git a/lib/blocs/search/search_event.dart b/lib/blocs/search/search_event.dart index fc7a7f8..560c088 100644 --- a/lib/blocs/search/search_event.dart +++ b/lib/blocs/search/search_event.dart @@ -1,10 +1,12 @@ +import 'package:flutter_unit/database/widget_dao.dart'; + abstract class SearchEvent{//事件基 const SearchEvent(); } class EventTextChanged extends SearchEvent { - final String arg;//参数 - const EventTextChanged(this.arg); + final SearchArgs args;//参数 + const EventTextChanged({this.args}); } diff --git a/lib/blocs/search/search_state.dart b/lib/blocs/search/search_state.dart index e71b29f..60254a3 100644 --- a/lib/blocs/search/search_state.dart +++ b/lib/blocs/search/search_state.dart @@ -1,5 +1,7 @@ +import 'package:flutter_unit/model/widget_model.dart'; + abstract class SearchState {//基态 const SearchState(); } @@ -12,6 +14,6 @@ class SearchStateLoading extends SearchState {}//加载中 class SearchStateError extends SearchState {}//异常 class SearchStateSuccess extends SearchState {//有结果 -// final SearchResult result;//搜索结果 -// const SearchStateSuccess(this.result); + final List result;//搜索结果 + const SearchStateSuccess(this.result); } diff --git a/lib/components/Destroy.dart b/lib/components/Destroy.dart deleted file mode 100644 index b9f82cf..0000000 --- a/lib/components/Destroy.dart +++ /dev/null @@ -1,167 +0,0 @@ -import 'dart:math'; -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -// 手动导入一下iamge包 -import 'package:image/image.dart' as image; - -/// create by 张风捷特烈 on 2020-03-31 -/// contact me by email 1981462002@qq.com -/// 说明: - -class Destroy extends StatefulWidget { - // 将需要沙化的内容包裹起来 - final Widget child; - - // 吹散动画的时间 - final Duration duration; - - // 图层数量 图层越多,吹散效果越好但是更耗时 - final int numberOfLayers; - - Destroy( - {Key key, - @required this.child, - this.duration = const Duration(seconds: 3), - this.numberOfLayers = 10}) - : super(key: key); - - @override - _DestroyState createState() => _DestroyState(); -} - -class _DestroyState extends State with TickerProviderStateMixin{ - // 吹散动画Controller - AnimationController _mainController; - - // key of child - GlobalKey _globalKey = GlobalKey(); - - // 重叠的分离图层 - List layers = []; - - @override - void initState() { - super.initState(); - - _mainController = - AnimationController(vsync: this, duration: widget.duration); - } - - @override - void dispose() { - _mainController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - children: [ - ...layers, // 沙化图层 - // 可点击的child 用RepaintBoundary包裹以截图 - GestureDetector( - onTap: () { - blow(); - }, - // 当动画开始 本体隐藏 - child: _mainController.isAnimating - ? Container() - : RepaintBoundary( - key: _globalKey, - child: widget.child, - ), - ) - ], - ); - } - Future blow() async { - // 获取到完整的图像 - image.Image fullImage = await _getImageFromWidget(); - - // 获取原图的宽高 - int width = fullImage.width; - int height = fullImage.height; - - // 初始化与原图相同大小的空白的图层 - List blankLayers = - List.generate(widget.numberOfLayers, (i) => image.Image(width, height)); - - // 将原图的像素点,分布到layer中 - separatePixels(blankLayers, fullImage, width, height); - - // 将图层转换为Widget - layers = blankLayers.map((layer) => imageToWidget(layer)).toList(); - - // 刷新页面 - setState(() {}); - - // 开始动画 - _mainController.forward(); - } - - void separatePixels(List blankLayers, image.Image fullImage, - int width, int height) { - // 遍历所有的像素点 - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - // 获取当前的像素点 - int pixel = fullImage.getPixel(x, y); - // 如果当前像素点是透明的 则直接continue 减少不必要的浪费 - if (0 == pixel) continue; - - // 随机生成放入的图层index - int index = Random().nextInt(widget.numberOfLayers); - // 将像素点放入图层 - blankLayers[index].setPixel(x, y, pixel); - } - } - } - // 将一个Widget转为image.Image对象 - Future _getImageFromWidget() async { - // _globalKey为需要图像化的widget的key - RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject(); - - // ui.Image => image.Image - var img = await boundary.toImage(); - var byteData = await img.toByteData(format: ImageByteFormat.png); - var pngBytes = byteData.buffer.asUint8List(); - - return image.decodeImage(pngBytes); - } - Widget imageToWidget(image.Image png) { - // 先将image 转换为 Uint8List 格式 - Uint8List data = Uint8List.fromList(image.encodePng(png)); - - // 定义一个先快后慢的动画过程曲线 - CurvedAnimation animation = CurvedAnimation( - parent: _mainController, curve: Interval(0, 1, curve: Curves.easeOut)); - - // 定义位移变化的插值(始末偏移量) - Animation offsetAnimation = Tween( - begin: Offset.zero, - // 基础偏移量+随机偏移量 - end: Offset(50, -20) + - Offset(30, 30).scale((Random().nextDouble() - 0.5) * 2, - (Random().nextDouble() - 0.5) * 2), - ).animate(animation); - - return AnimatedBuilder( - animation: _mainController, - child: Image.memory(data), - builder: (context, child) { - // 位移动画 - return Transform.translate( - offset: offsetAnimation.value, - // 渐隐动画 - child: Opacity( - opacity: cos(animation.value * pi / 2), // 1 => 0 - child: child, - ), - ); - }, - ); - } -} diff --git a/lib/components/code/code_panel.dart b/lib/components/code/code_panel.dart index d93cf85..1fa519e 100755 --- a/lib/components/code/code_panel.dart +++ b/lib/components/code/code_panel.dart @@ -1,40 +1,42 @@ import 'package:flutter/material.dart'; import 'high_light_code.dart'; - +import 'highlighter_style.dart'; class CodeWidget extends StatelessWidget { - - CodeWidget({Key key,@required this.code}):super(key:key); + CodeWidget({Key key, @required this.code, this.style, this.fontSize = 13,this.fontFamily}) + : super(key: key); final String code; + final HighlighterStyle style; + final double fontSize; + final String fontFamily; @override Widget build(BuildContext context) { - final SyntaxHighlighterStyle style = - Theme.of(context).brightness == Brightness.dark - ? SyntaxHighlighterStyle.darkThemeStyle() - : SyntaxHighlighterStyle.lightThemeStyle(); - Widget body; if (code == null) { return Container(); } else { Widget _codeWidget; - try{ - DartSyntaxHighlighter(style).format(code); + try { _codeWidget = RichText( text: TextSpan( - style: const TextStyle(fontSize: 13.0), - children: [ - DartSyntaxHighlighter(style).format(code) - ],), + style: TextStyle(fontSize: fontSize,fontFamily: fontFamily), + children: [DartHighlighter(style).format(code)], + ), ); - }catch (err){ + } catch (err) { _codeWidget = Text(code); } body = SingleChildScrollView( + child: Container( child: _codeWidget, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: style.backgroundColor ?? Color(0xffF6F8FA), + borderRadius: BorderRadius.all(Radius.circular(5.0))), + ), ); } return body; diff --git a/lib/components/code/high_light_code.dart b/lib/components/code/high_light_code.dart index e964fd9..654d207 100755 --- a/lib/components/code/high_light_code.dart +++ b/lib/components/code/high_light_code.dart @@ -5,69 +5,25 @@ import 'package:flutter/material.dart'; import 'package:string_scanner/string_scanner.dart'; +import 'highlighter_style.dart'; + /// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle(); /// DartSyntaxHighlighter(style).format(source) -class SyntaxHighlighterStyle {//句法高亮样式 - SyntaxHighlighterStyle({//构造函数 - this.baseStyle,//基础样式 - this.numberStyle,//数字的样式 - this.commentStyle,//注释样式 - this.keywordStyle,//关键字样式 - this.stringStyle,//字符串样式 - this.punctuationStyle,//标点符号样式 - this.classStyle, - this.constantStyle - }); - static SyntaxHighlighterStyle lightThemeStyle() { - return SyntaxHighlighterStyle( - baseStyle: const TextStyle(color: Color(0xFF000000)),//黑色 - numberStyle: const TextStyle(color: Color(0xFF1565C0)), - commentStyle: const TextStyle(color: Color(0xFF9E9E9E)), - keywordStyle: const TextStyle(color: Color(0xFF9C27B0)), - stringStyle: const TextStyle(color: Color(0xFF43A047)), - punctuationStyle: const TextStyle(color: Color(0xFF000000)), - classStyle: const TextStyle(color: Color(0xFF512DA8)), - constantStyle: const TextStyle(color: Color(0xFF795548)) - ); - } - - static SyntaxHighlighterStyle darkThemeStyle() { - return SyntaxHighlighterStyle( - baseStyle: const TextStyle(color: Color(0xFFFFFFFF)), - numberStyle: const TextStyle(color: Color(0xFF1565C0)), - commentStyle: const TextStyle(color: Color(0xFF9E9E9E)), - keywordStyle: const TextStyle(color: Color(0xFF80CBC4)), - stringStyle: const TextStyle(color: Color(0xFF009688)), - punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)), - classStyle: const TextStyle(color: Color(0xFF009688)), - constantStyle: const TextStyle(color: Color(0xFF795548)) - ); - } - - final TextStyle baseStyle; - final TextStyle numberStyle; - final TextStyle commentStyle; - final TextStyle keywordStyle; - final TextStyle stringStyle; - final TextStyle punctuationStyle; - final TextStyle classStyle; - final TextStyle constantStyle; -} abstract class Highlighter { // ignore: one_member_abstracts TextSpan format(String src); } //暗黑模式下的高亮样式 -class DartSyntaxHighlighter extends Highlighter { - DartSyntaxHighlighter([this._style]) { +class DartHighlighter extends Highlighter { + DartHighlighter([this._style]) { _spans = <_HighlightSpan>[]; - _style ??= SyntaxHighlighterStyle.darkThemeStyle(); + _style ??= HighlighterStyle.fromColors(HighlighterStyle.lightColor); } - SyntaxHighlighterStyle _style; + HighlighterStyle _style; static const List _keywords = [ 'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch', @@ -339,7 +295,7 @@ class _HighlightSpan { return src.substring(start, end); } - TextStyle textStyle(SyntaxHighlighterStyle style) { + TextStyle textStyle(HighlighterStyle style) { if (type == _HighlightType.number) return style.numberStyle; else if (type == _HighlightType.comment) diff --git a/lib/components/code/highlighter_style.dart b/lib/components/code/highlighter_style.dart new file mode 100644 index 0000000..b472777 --- /dev/null +++ b/lib/components/code/highlighter_style.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020-04-11 +/// contact me by email 1981462002@qq.com +/// 说明: + + +class HighlighterStyle { + //句法高亮样式 + const HighlighterStyle( + { //构造函数 + this.baseStyle, //基础样式 + this.numberStyle, //数字的样式 + this.commentStyle, //注释样式 + this.keywordStyle, //关键字样式 + this.stringStyle, //字符串样式 + this.punctuationStyle, //标点符号样式 + this.classStyle, //类名 + this.backgroundColor, + this.constantStyle}); + + static List get lightColor => [ + 0xFF000000, //基础 + 0xFF00b0e8, //数字 + 0xFF9E9E9E, //注释 + 0xFF9C27B0, //关键 + 0xFF43A047, //字符串 + 0xFF000000, //标点符号 + 0xFF3D62F5, //类名 + 0xFF795548, //常量 + 0xffF6F8FA, //背景 + ]; + + static List get darkColor => [ + 0xFFFFFFFF, //基础 + 0xFFDF935F, //数字 + 0xFF9E9E9E, //注释 + 0xFF80CBC4, //关键字 + 0xFFB9CA4A, //字符串 + 0xFFFFFFFF, //标点符号 + 0xFF7AA6DA, //类名 + 0xFF795548, //常量 + 0xFF1D1F21, //背景 + ]; + + static List get gitHub => + [ + 0xFF333333, //基础 + 0xFF008081, //数字 + 0xFF9D9D8D, //注释 + 0xFF009999, //关键字 + 0xFFDD1045, //字符串 + 0xFF333333, //标点符号 + 0xFF6F42C1, //类名 + 0xFF795548, //常量 + 0xFFF8F8F8, //背景 + ]; + + static List get zenburn => [ + 0xFFDCDCDC, //普通字 + 0xFF87C5C8, //数字 + 0xFF8F8F8F, //注释 + 0xFFE4CEAB, //关键字 + 0xFFCC9493, //字符串 + 0xFFDCDCDC, //标点符号 + 0xFFEFEF90, //类名 + 0xFFEF5350, //常量 + 0xFF3F3F3F, //背景 + ]; + + static List get mf =>[ + 0xFF707D95, //基础 + 0xFF6897BB, //数字 + 0xFF629755, //注释 + 0xFFCC7832, //关键 + 0xFFF14E9F, //字符串 + 0xFFFFBB33, //标点符号 + 0xFF66CCFF, //类名 + 0xFF9876AA, //常量 + 0xFF2B2B2B //背景 + ]; + + factory HighlighterStyle.fromColors(List colors) => HighlighterStyle( + baseStyle: TextStyle( + color: Color(colors[0]), + ), + numberStyle: TextStyle( + color: Color(colors[1]), + ), + commentStyle: TextStyle( + color: Color( + colors[2], + ), + fontStyle: FontStyle.italic), + keywordStyle: TextStyle( + fontWeight: FontWeight.bold, + color: Color( + colors[3], + ), + ), + stringStyle: TextStyle( + color: Color(colors[4]), + ), + punctuationStyle: TextStyle( + color: Color(colors[5]), + ), + classStyle: TextStyle( + color: Color(colors[6]), + ), + constantStyle: TextStyle( + color: Color(colors[7]), + ), + backgroundColor: Color(colors[8]), + ); + final TextStyle baseStyle; + final TextStyle numberStyle; + final TextStyle commentStyle; + final TextStyle keywordStyle; + final TextStyle stringStyle; + final TextStyle punctuationStyle; + final TextStyle classStyle; + final TextStyle constantStyle; + final Color backgroundColor; +} diff --git a/lib/components/expend_panel.dart b/lib/components/expend_panel.dart deleted file mode 100644 index 75f0af8..0000000 --- a/lib/components/expend_panel.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -/// create by 张风捷特烈 on 2020-03-19 -/// contact me by email 1981462002@qq.com -/// 说明: - - -class ExpendPanel extends StatefulWidget { - @override - _ExpendPanelState createState() => _ExpendPanelState(); -} - -class _ExpendPanelState extends State - with SingleTickerProviderStateMixin { - AnimationController _ctrl; - double _sizeFactor = 0; - Animation _expend; - bool _opened = false; - - @override - void initState() { - _ctrl = - AnimationController(vsync: this, duration: Duration(milliseconds: 500)) - ..addListener(() { - setState(() { - _sizeFactor = (_opened ? (1 - _expend.value) : _expend.value); - }); - }) - ..addStatusListener((s) { - if (s == AnimationStatus.completed) { - setState(() { - _opened = !_opened; - }); - } - }); - _expend = Tween(begin: 0.0, end: 1.0).animate(_ctrl); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Column( - children: [ - GestureDetector( - onTap: () { - _ctrl.reset(); - _ctrl.forward(); - }, - child: Icon(Icons.arrow_upward)), - ClipRect( - child: Align( - alignment: Alignment.center, - heightFactor: _sizeFactor, - child: Container( - width: MediaQuery.of(context).size.width, - height: 200, - color: Colors.orange, - child: Icon(Icons.android, color: Colors.green, size: 80)), - ), - ) - ], - ); - } -} diff --git a/lib/components/feedback_widget.dart b/lib/components/feedback_widget.dart new file mode 100644 index 0000000..36a148e --- /dev/null +++ b/lib/components/feedback_widget.dart @@ -0,0 +1,82 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +enum FeedMode { + scale, + fade, + rotate, +} + +class FeedbackWidget extends StatefulWidget { + final Widget child; + final FeedMode mode; + final Duration duration; + final Function() onPressed; + final a; + + FeedbackWidget( + {@required this.child, + this.mode = FeedMode.scale, + this.a = 0.9, + this.duration = const Duration(milliseconds: 150), + @required this.onPressed}); + + @override + _FeedBackState createState() => _FeedBackState(); +} + +class _FeedBackState extends State + with SingleTickerProviderStateMixin { + AnimationController _controller; + var rate = 1.0; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: widget.duration) + ..addListener(() { + setState(() => rate = (widget.a - 1) * _controller.value + 1); + }) + ..addStatusListener((s) { + if (s == AnimationStatus.completed) { + _controller.reverse(); + } + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + _controller.forward(); + if(widget.onPressed!=null){ + widget.onPressed(); + } + }, + child: _buildByMode(widget.child, widget.mode), + ); + } + + Widget _buildByMode(Widget child, FeedMode mode) { + switch (mode) { + case FeedMode.scale: + return Transform.scale(scale: rate, child: widget.child); + case FeedMode.fade: + return Opacity(opacity: rate, child: widget.child); + case FeedMode.rotate: + return Transform.rotate(angle: rate * pi * 2, child: widget.child); + } + return Container(); + } +} diff --git a/lib/components/flutter_container.dart b/lib/components/flutter_container.dart deleted file mode 100644 index 477009e..0000000 --- a/lib/components/flutter_container.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -enum FlutterMode { - //颤动的模式 - random, //随机模式 - up_down, //上下 - left_right, //左右 - swing //倾斜 -} - -class AnimConfig { - //动画配置信息 - final int duration; //时长 - final double offset; //偏移大小 - final FlutterMode mode; //摇晃模式 - final Curve curve; //运动曲线 - - const AnimConfig( - {this.duration = 1000, - this.offset = 15, - this.mode = FlutterMode.swing, - this.curve = Curves.bounceIn}); -} - -class FlutterContainer extends StatefulWidget { - final Widget child; - final AnimConfig config; - final VoidCallback onFinish; - - FlutterContainer( - {Key key, - @required this.child, //孩子 - this.config = const AnimConfig(), //配置 - this.onFinish} //动画结束回调 - ) - : super(key: key); - - _FlutterContainerState createState() => _FlutterContainerState(); -} - -class _FlutterContainerState extends State - with SingleTickerProviderStateMixin { - Animation animation; - AnimationController controller; - Animation animationRotate; - var random = Random(); - - @override - initState() { - controller = AnimationController( - duration: const Duration(milliseconds: 1000), vsync: this); - - var offset = widget.config.offset; //偏移量 - var offsets = []; //起止值的列表盛放在offsets里 - offsets.add(Offset(0, offset)); //添加第一个 - var temp = offset; //临时变量 - for (var i = 1; i <= offset; i++) { - temp--; //临时变量减小 - offsets.add(i.isOdd ? Offset(temp, -temp) : Offset(-temp, temp)); //动态添加 - } - print(offsets); - animation = TweenSequence(offsets - .map((e) => TweenSequenceItem( - tween: Tween(begin: e.dx, end: e.dy), weight: 1)) - .toList()) - .animate(CurveTween(curve: widget.config.curve).animate(controller)) - ..addStatusListener((s) {//添加完成回调 - if (s == AnimationStatus.completed) { - if (widget.onFinish != null) widget.onFinish(); - } - }); - controller.forward(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - switch (widget.config.mode) { - case FlutterMode.up_down: //上下效果 - return AnimUpDown( - animation: animation, - child: widget.child, - ); - - case FlutterMode.left_right: //左右效果 - return AnimLeftRight( - animation: animation, - child: widget.child, - ); - - case FlutterMode.swing: //摇摆效果 - animationRotate = - Tween(begin: 0.0, end: pi / 180).animate(animation); //将参数转化为弧度 - return AnimRotate( - animation: animationRotate, - child: widget.child, - ); - - case FlutterMode.random: //随机效果 - var config = AnimConfig( - mode: FlutterMode.values[random.nextInt(FlutterMode.values.length)], - duration: widget.config.duration, - offset: widget.config.offset, - curve: widget.config.curve); - return FlutterContainer( - onFinish: widget.onFinish, - child: widget.child, - config: config, - ); - break; - } - } - - @override - dispose() { - controller.dispose(); - super.dispose(); - } -} - -class AnimRotate extends AnimatedWidget { - AnimRotate({Key key, Animation animation, this.child}) - : super(key: key, listenable: animation); - final Widget child; //孩子组件 - @override - Widget build(BuildContext context) { - final Animation animation = listenable; //获取动画器 - return Transform( - //根据动画器数值对孩子进行旋转 - child: child, - alignment: Alignment.center, - transform: Matrix4.rotationZ(animation.value), - ); - } -} - -//左右动画 -class AnimLeftRight extends AnimatedWidget { - AnimLeftRight({Key key, Animation animation, this.child}) - : super(key: key, listenable: animation); - final Widget child; - - @override - Widget build(BuildContext context) { - final Animation animation = listenable; - return Transform( - transform: Matrix4.translationValues(animation.value, 0, 0), - alignment: Alignment.center, - child: child, - ); - } -} - -//上下效果 -class AnimUpDown extends AnimatedWidget { - AnimUpDown({Key key, Animation animation, this.child}) - : super(key: key, listenable: animation); - final Widget child; - - @override - Widget build(BuildContext context) { - final Animation animation = listenable; - return Transform( - alignment: Alignment.center, - child: child, - transform: Matrix4.translationValues(0, animation.value, 0), - ); - } -} diff --git a/lib/components/flutter_text.dart b/lib/components/flutter_text.dart deleted file mode 100644 index 7df9b4c..0000000 --- a/lib/components/flutter_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import 'flutter_container.dart'; - -class FlutterText extends StatelessWidget { - final String str; - final TextStyle style; - final AnimConfig config; - FlutterText(this.str, {Key key, this.style, this.config=const AnimConfig()}):super(key:key); - - @override - Widget build(BuildContext context) => - Wrap(children: str.split("").map((e)=> - FlutterContainer( - config: config, - child: Text(e, style: style),)).toList() - ); - -} \ No newline at end of file diff --git a/lib/components/multi_shower.dart b/lib/components/multi_shower.dart deleted file mode 100755 index 7bdcf9f..0000000 --- a/lib/components/multi_shower.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:flutter/material.dart'; - -class MultiShower extends StatelessWidget { - MultiShower( - this.list, - this.call, { - this.width = 110, - this.height = 110 * 0.618, - this.info, - this.color = Colors.cyanAccent, - }); - - final List list;//数据 - final List info;//底部介绍 - final Function call;//回调 - final double width;//单体宽 - final double height;//单体高 - final Color color;//颜色 - - @override - Widget build(BuildContext context) { - - return SingleChildScrollView(child: Center( - child: Wrap( - children: list.map((e) => Column( - children: [ - Card( - child: Container( - margin: EdgeInsets.all(2), - color: color, - width: width, - height: height, - child: call(e)), - ), - Padding( - padding: EdgeInsets.only(bottom: 3), - child: Text(_getInfo(list.indexOf(e)),style: TextStyle(fontSize: 12),)) - ], - )).toList(), - ), - )); - } - - String _getInfo(int index) { - var result="请添加info属性"; - if(info==null){ - var splits=list[index].toString().split("."); - if (splits.length>1){ - result= splits[1]; - } - }else{ - result=info[index]; - } - return result; - } -} - -///------------测试 --------- -/// -var show = MultiShower( - BlendMode.values, - (mode) => Image( - image: AssetImage("assets/images/icon_head.png"), - color: Colors.blue, - colorBlendMode: mode, - ), - width: 56, - height: 56, -); diff --git a/lib/components/panel/circle.dart b/lib/components/panel/circle.dart index 301cb98..5eb4b97 100644 --- a/lib/components/panel/circle.dart +++ b/lib/components/panel/circle.dart @@ -3,17 +3,28 @@ import 'package:flutter/material.dart'; class Circle extends StatelessWidget { final Color color; final double radius; + final bool showShadow; + final Widget child; - Circle({this.color=Colors.blue, this.radius=6}); + Circle({this.color=Colors.blue, this.radius=6,this.showShadow=true,this.child}); @override Widget build(BuildContext context) { return Container( + alignment: Alignment.center, + child: child==null?Container():child, width: 2*radius, height: 2*radius, decoration: BoxDecoration( color: color, - shape: BoxShape.circle + shape: BoxShape.circle, + boxShadow: [ + if (showShadow) + BoxShadow( + color: Colors.grey, + offset: Offset(.5,.5), + blurRadius: .5, + )] ), ); } diff --git a/lib/components/panel/panel.dart b/lib/components/panel/panel.dart index fbd8705..f681e69 100644 --- a/lib/components/panel/panel.dart +++ b/lib/components/panel/panel.dart @@ -1,6 +1,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; import 'package:flutter_unit/components/code/code_panel.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; import 'package:toggle_rotate/toggle_rotate.dart'; import 'circle.dart'; @@ -29,8 +33,10 @@ class NodePanel extends StatefulWidget { final String subText; final String code; final Widget show; + final HighlighterStyle codeStyle; + final String codeFamily; - NodePanel({this.text, this.subText, this.code, this.show}); + NodePanel({this.text, this.subText, this.code, this.show,this.codeStyle,this.codeFamily}); @override _NodePanelState createState() => _NodePanelState(); @@ -42,7 +48,7 @@ class _NodePanelState extends State var _crossFadeState = CrossFadeState.showFirst; - bool get isFirst=> _crossFadeState == CrossFadeState.showFirst; + bool get isFirst => _crossFadeState == CrossFadeState.showFirst; @override Widget build(BuildContext context) { @@ -56,7 +62,7 @@ class _NodePanelState extends State Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Circle( - color: Colors.orange, + color: Theme.of(context).primaryColor, radius: 5, ), ), @@ -66,15 +72,42 @@ class _NodePanelState extends State style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), ), + FeedbackWidget( + mode: FeedMode.fade, + a: 0.4, + onPressed: () async { + await Clipboard.setData(ClipboardData(text: widget.code)); + Scaffold.of(context).showSnackBar(SnackBar( + content: Text('复制成功!'), + duration: Duration(milliseconds: 600), + backgroundColor: Theme.of(context).primaryColor, + )); + }, + child: Padding( + padding: const EdgeInsets.only( + right: 10, + ), + child: Icon( + Icons.content_copy, + size: 20, + color: Theme.of(context).primaryColor, + ), + ), + ), Padding( padding: const EdgeInsets.only(right: 10.0), child: ToggleRotate( durationMs: 300, - child: Icon(Icons.code,color: Colors.orange,), + child: Icon( + TolyIcon.icon_code, + color: Theme.of(context).primaryColor, + ), onTap: () { setState(() { - _crossFadeState= _showCode?CrossFadeState.showFirst:CrossFadeState.showSecond; - _showCode=!_showCode; + _crossFadeState = _showCode + ? CrossFadeState.showFirst + : CrossFadeState.showSecond; + _showCode = !_showCode; }); }, ), @@ -103,20 +136,20 @@ class _NodePanelState extends State ); } - Widget _buildCode(BuildContext context) =>AnimatedCrossFade( - firstCurve: Curves.easeInCirc, - secondCurve: Curves.easeInToLinear, - firstChild: Container(), - secondChild: Container( - width: MediaQuery.of(context).size.width, - child: Panel( - child: CodeWidget( - code: widget.code, + Widget _buildCode(BuildContext context) => AnimatedCrossFade( + firstCurve: Curves.easeInCirc, + secondCurve: Curves.easeInToLinear, + firstChild: Container(), + secondChild: Container( + width: MediaQuery.of(context).size.width, + child: CodeWidget( + fontFamily: widget.codeFamily, + code: widget.code, + style: widget.codeStyle??HighlighterStyle.fromColors( + HighlighterStyle.lightColor), + ), ), - ), - ), - duration: Duration(milliseconds: 500), - crossFadeState: _crossFadeState, - ); - + duration: Duration(milliseconds: 500), + crossFadeState: _crossFadeState, + ); } diff --git a/lib/components/toly_app_bar.dart b/lib/components/toly_app_bar.dart index 14dd56f..8b68813 100644 --- a/lib/components/toly_app_bar.dart +++ b/lib/components/toly_app_bar.dart @@ -47,7 +47,6 @@ class _TolyAppBarState extends State return Container( alignment: Alignment.center, -// color: Color(colors[nextIndex]).withAlpha(33), child: Flow( delegate: TolyAppBarDelegate( _selectIndex, factor, widget.preferredSize.height), @@ -113,7 +112,6 @@ class TolyAppBarDelegate extends FlowDelegate { void paintChildren(FlowPaintingContext context) { double ox = 0; double obx = 0; -// var size = context.size; for (int i = 0; i < context.childCount / 2; i++) { var cSize = context.getChildSize(i); @@ -130,12 +128,8 @@ class TolyAppBarDelegate extends FlowDelegate { for (int i = (context.childCount / 2).floor(); i < context.childCount; i++) { - var cSize = context.getChildSize(i); if (i - (context.childCount / 2).floor() == selectIndex) { obx += context.getChildSize(0).width; -// context.paintChild(i, -// transform: Matrix4.translationValues(ox, 20.0 * factor - 20, 0.0)); -// ox += cSize.width; } else { context.paintChild(i, transform: Matrix4.translationValues( @@ -150,49 +144,3 @@ class TolyAppBarDelegate extends FlowDelegate { return true; } } - -class _DrawShape extends ShapeBorder { - final double itemWidth; - final int selectedIndex; - final Size preferredSize; - final List colors; - - Paint _paint; - - _DrawShape( - {this.itemWidth, this.selectedIndex, this.colors, this.preferredSize}) { - _paint = Paint(); - } - - @override - EdgeInsetsGeometry get dimensions => null; - - @override - Path getInnerPath(Rect rect, {TextDirection textDirection}) { - return null; - } - - @override - Path getOuterPath(Rect rect, {TextDirection textDirection}) { - return null; - } - - @override - void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) { - print(rect); - for (int i = 0; i < 7; i++) { - if (i != selectedIndex) { - canvas.save(); - canvas.translate(itemWidth * i, 0); - canvas.drawCircle(Offset(itemWidth / 2, preferredSize.height + 10), 6, - _paint..color = Color(colors[i])); - canvas.restore(); - } - } - } - - @override - ShapeBorder scale(double t) { - return null; - } -} diff --git a/lib/database/flutter_db.dart b/lib/database/flutter_db.dart index abfdfd0..37323f3 100644 --- a/lib/database/flutter_db.dart +++ b/lib/database/flutter_db.dart @@ -19,7 +19,7 @@ class FlutterDb { id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(64) NOT NULL UNIQUE, nameCN VARCHAR(12) NOT NULL, - childCount INTEGER NOT NULL DEFAULT 0, + collected INTEGER DEFAULT 0, family INTEGER NOT NULL, lever FLOAT(2) NOT NULL, image VARCHAR(128) NOT NULL, @@ -37,6 +37,20 @@ class FlutterDb { code TEXT NOT NULL );"""; //建表语句 + static const String sql_create_category = """ + CREATE TABLE IF NOT EXISTS category( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR(64) NOT NULL, + info VARCHAR(128) + );"""; //建表语句 + + static const String sql_create_category_widget = """ + CREATE TABLE IF NOT EXISTS category_widget( + id INTEGER PRIMARY KEY AUTOINCREMENT, + widgetId INTEGER NOT NULL, + categoryId INTEGER NOT NULL + );"""; //建表语句 + Future initDB() async { //初始化数据库 WidgetsFlutterBinding.ensureInitialized(); //初始化绑定 @@ -51,6 +65,8 @@ class FlutterDb { print("数据库-------onCreate"); await db.execute(sql_create_widget); await db.execute(sql_create_node); + await db.execute(sql_create_category); + await db.execute(sql_create_category_widget); }, ); } diff --git a/lib/database/po/widget_po.dart b/lib/database/po/widget_po.dart index 12a2cb5..507e0fe 100644 --- a/lib/database/po/widget_po.dart +++ b/lib/database/po/widget_po.dart @@ -7,7 +7,7 @@ class WidgetPo extends Equatable { final int id; final String name; final String nameCN; - final int childCount; + final int collected; final int family; final double lever; final String image; @@ -18,7 +18,7 @@ class WidgetPo extends Equatable { {this.id, this.name, this.nameCN, - this.childCount, + this.collected, this.family, this.lever, this.linkWidget, @@ -31,7 +31,7 @@ class WidgetPo extends Equatable { name: map['name'], nameCN: map["nameCN"], family: map["family"], - childCount: map["childCount"], + collected: map["collected"]??0, lever: map["lever"].toDouble(), image: map["image"], linkWidget: map["linkWidget"], @@ -40,10 +40,10 @@ class WidgetPo extends Equatable { @override String toString() { - return 'WidgetPo{id: $id, name: $name, nameCN: $nameCN, childCount: $childCount, family: $family, lever: $lever, image: $image, info: $info}'; + return 'WidgetPo{id: $id, name: $name, nameCN: $nameCN, collected: $collected, family: $family, lever: $lever, image: $image, info: $info}'; } @override List get props => - [id, name, nameCN, childCount, family, lever, image, info]; + [id, name, nameCN, collected, family, lever, image, info]; } diff --git a/lib/database/widget_dao.dart b/lib/database/widget_dao.dart index 6e81b10..3c443d1 100644 --- a/lib/database/widget_dao.dart +++ b/lib/database/widget_dao.dart @@ -1,3 +1,4 @@ +import 'package:flutter_unit/app/enums.dart'; import 'po/widget_po.dart'; @@ -9,13 +10,13 @@ class WidgetDao { final db = await FlutterDb.db.database; String addSql = //插入数据 "INSERT INTO " - "widget(id,name,nameCN,childCount,family,lever,image,linkWidget,info) " + "widget(id,name,nameCN,collected,family,lever,image,linkWidget,info) " "VALUES (?,?,?,?,?,?,?,?,?);"; return await db.transaction((tran) async => await tran.rawInsert(addSql, [ widget.id, widget.name, widget.nameCN, - widget.childCount, + widget.collected, widget.family, widget.lever, widget.image, @@ -25,11 +26,57 @@ class WidgetDao { } Future>> queryAll() async { - //插入方法 final db = await FlutterDb.db.database; return await db.rawQuery("SELECT * " "FROM widget"); -// var list = data.map((e)=>WidgetPo.fromJson(e)).toList(); -// return list; + } + + Future>> queryByFamily(WidgetFamily family) async { + final db = await FlutterDb.db.database; + return await db.rawQuery( + "SELECT * " + "FROM widget WHERE family = ?", + [family.index]); + } + + Future>> queryByIds(List ids) async { + final db = await FlutterDb.db.database; + + var sql = "SELECT * " + "FROM widget WHERE id in (${'?,' * (ids.length - 1)}?) "; + + return await db.rawQuery(sql, [...ids]); + } + + Future>> search(SearchArgs arguments) async { + final db = await FlutterDb.db.database; + return await db.rawQuery( + "SELECT * " + "FROM widget WHERE name like ? AND lever IN(?,?,?,?,?) ORDER BY lever DESC", + ["%${arguments.name}%", ...arguments.stars]); + } + + Future>> toggleCollect(int id) async { + final db = await FlutterDb.db.database; + var data = await db.rawQuery('SELECT collected FROM widget WHERE id = ?', [id]); + var collected = data.toList()[0]['collected']==1; + print('collected:$collected'); + return await db.rawQuery( + "UPDATE widget SET collected = ? " + "WHERE id = ?", + [collected ? 0 : 1, id]); + } + + Future>> queryCollect() async { + final db = await FlutterDb.db.database; + return await db.rawQuery("SELECT * " + "FROM widget WHERE collected = 1 ORDER BY family,lever DESC"); } } + +class SearchArgs { + final String name; + final List stars; + + const SearchArgs({this.name = '', this.stars = const [-1, -1, -1, -1, -1]}); +} diff --git a/lib/main.dart b/lib/main.dart index 1a61353..d2e7e7f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,13 +2,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_unit/app/enums.dart'; import 'package:flutter_unit/blocs/search/search_bloc.dart'; +import 'package:flutter_unit/repositorys/widget_db_repository.dart'; import 'package:flutter_unit/repositorys/widget_me_repository.dart'; import 'package:flutter_unit/views/unit_splash.dart'; -import 'package:flutter_unit/views/widgets/StatefulWidget/Checkbox.dart'; import 'app/initial.dart'; +import 'blocs/collect/collect_bloc.dart'; import 'blocs/detail/detail_bloc.dart'; import 'blocs/global/global_bloc.dart'; +import 'blocs/global/global_event.dart'; +import 'blocs/global/global_state.dart'; import 'blocs/widgets/widget_bloc.dart'; import 'blocs/widgets/widget_event.dart'; @@ -38,14 +41,16 @@ class BlocWrapper extends StatelessWidget { return MultiBlocProvider(//使用MultiBlocProvider包裹 providers: [ //Bloc提供器 + BlocProvider(create: (_) => GlobalBloc()..add(EventInitApp())), BlocProvider( create: (_) => WidgetBloc(repository: repository) ..add(LoadWidget(WidgetFamily.statelessWidget))), BlocProvider( create: (_) => DetailBloc(repository: repository)), - BlocProvider(create: (_) => GlobalBloc()), - BlocProvider(create: (_) => SearchBloc()), + + BlocProvider(create: (_) => CollectBloc(repository: repository)), + BlocProvider(create: (_) => SearchBloc(repository: repository)), ], child: child); } } @@ -53,17 +58,22 @@ class BlocWrapper extends StatelessWidget { class FlutterApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( + return BlocBuilder( + builder: (_, state) { + print(state.themeColor); + return MaterialApp( title: 'Flutter Demo', onGenerateRoute: Router.generateRoute, theme: ThemeData( - primarySwatch: Colors.blue, + primarySwatch: state.themeColor, + fontFamily: state.fontFamily, ), home: // NavPage() UnitSplash() // UnitNavigation(), ); + }); } } //NavPage() diff --git a/lib/model/widget_model.dart b/lib/model/widget_model.dart index a52b69f..9a1ce05 100644 --- a/lib/model/widget_model.dart +++ b/lib/model/widget_model.dart @@ -20,7 +20,9 @@ class WidgetModel extends Equatable { final String name; final String nameCN; final WidgetFamily family; + final bool collected; final WidgetType type; + final List links; final double lever; final ImageProvider image; final String info; @@ -32,13 +34,15 @@ class WidgetModel extends Equatable { this.name, this.nameCN, this.family, + this.collected, + this.links, this.type, this.lever, this.image, this.info}); @override - List get props => [name, nameCN, family, type, lever, image, info]; + List get props => [id]; static WidgetModel fromPo(WidgetPo po) { return WidgetModel( @@ -48,11 +52,30 @@ class WidgetModel extends Equatable { family: Convert.toFamily(po.family), image: convertImage(po.image), lever: po.lever, + collected: po.collected == 1, info: po.info, + links: formatLinkTo(po.linkWidget), ); } static convertImage(String image) { return image.isEmpty ? null : AssetImage(image); } + + @override + String toString() { + return 'WidgetModel{id: $id, name: $name,collected: $collected}'; + } + + static List formatLinkTo(String links) { + if(links.isEmpty){ + return []; + } + if(!links.contains(',')){ + return [int.parse(links)]; + } + return links.split(',').map((e)=>int.parse(e)).toList(); + } + + } diff --git a/lib/repositorys/widget_db_repository.dart b/lib/repositorys/widget_db_repository.dart index 2b97870..f41e408 100644 --- a/lib/repositorys/widget_db_repository.dart +++ b/lib/repositorys/widget_db_repository.dart @@ -24,7 +24,23 @@ class WidgetDbRepository implements WidgetRepository { @override Future> loadWidgets(WidgetFamily family) async { - var data = await _widgetDao.queryAll(); + var data = await _widgetDao.queryByFamily(family); + var widgets = data.map((e) => WidgetPo.fromJson(e)).toList(); + return widgets.map(WidgetModel.fromPo).toList(); + } + + @override + Future> loadCollectWidgets() async { + var data = await _widgetDao.queryCollect(); + var widgets = data.map((e) => WidgetPo.fromJson(e)).toList(); + var list = widgets.map(WidgetModel.fromPo).toList(); + print(list); + return list; + } + + @override + Future> searchWidgets(SearchArgs args) async { + var data = await _widgetDao.search(args); var widgets = data.map((e) => WidgetPo.fromJson(e)).toList(); return widgets.map(WidgetModel.fromPo).toList(); } @@ -35,4 +51,17 @@ class WidgetDbRepository implements WidgetRepository { var nodes = data.map((e) => NodeModel.fromJson(e)).toList(); return nodes; } + + @override + Future> loadWidget(List id) async{ + var data = await _widgetDao.queryByIds(id); + var widgets = data.map((e) => WidgetPo.fromJson(e)).toList(); + if(widgets.length>0) return widgets.map(WidgetModel.fromPo).toList(); + return null; + } + + @override + Future toggleCollect(int id,) { + return _widgetDao.toggleCollect(id); + } } diff --git a/lib/repositorys/widget_me_repository.dart b/lib/repositorys/widget_me_repository.dart index 27e399f..3c4615c 100644 --- a/lib/repositorys/widget_me_repository.dart +++ b/lib/repositorys/widget_me_repository.dart @@ -33,4 +33,31 @@ class WidgetMeRepository implements WidgetRepository { Future> loadNode(WidgetModel widgetModel) async{ return nodeData[widgetModel.name].map((e)=>NodeModel.fromJson(e)).toList(); } + + @override + Future> searchWidgets(SearchArgs args) { + return null; + } + + @override + Future> loadWidget(List ids) async{ + var jsonStr = await rootBundle.loadString('assets/data/widget.json'); + var widgets = (json.decode(jsonStr)["items"] as List) + .map((item) => WidgetPo.fromJson(item)) + .toList(); + var where = widgets.map(WidgetModel.fromPo).where((e)=>ids.contains(e.id)).toList(); + return where; + } + + @override + Future> loadCollectWidgets() async{ + // TODO: implement loadCollectWidgets + return []; + } + + @override + Future toggleCollect(int id) { + // TODO: implement setCollect + return null; + } } diff --git a/lib/repositorys/widget_repository.dart b/lib/repositorys/widget_repository.dart index bb5e299..96d5331 100644 --- a/lib/repositorys/widget_repository.dart +++ b/lib/repositorys/widget_repository.dart @@ -1,6 +1,7 @@ import 'package:flutter_unit/app/enums.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; import 'package:flutter_unit/model/node_model.dart'; import 'package:flutter_unit/model/widget_model.dart'; @@ -10,6 +11,14 @@ import 'package:flutter_unit/model/widget_model.dart'; abstract class WidgetRepository { Future> loadWidgets(WidgetFamily family); + + Future> loadWidget(List ids); + + + Future> searchWidgets(SearchArgs args); Future> loadNode(WidgetModel widgetModel); + Future toggleCollect(int id); + Future> loadCollectWidgets(); + } \ No newline at end of file diff --git a/lib/views/empty_page.dart b/lib/views/empty_page.dart index 30dc306..5b1fafe 100644 --- a/lib/views/empty_page.dart +++ b/lib/views/empty_page.dart @@ -7,18 +7,19 @@ import 'package:flutter/material.dart'; class EmptyPage extends StatelessWidget { @override Widget build(BuildContext context) { - return new Container( - alignment: FractionalOffset.center, - child: new Column( + return Container( + height: 300, + alignment: Alignment.center, + child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - new Icon(Icons.style, color: Colors.grey, size: 80.0), - new Container( - padding: new EdgeInsets.only(top: 16.0), - child: new Text( + Icon(Icons.style, color: Colors.grey, size: 80.0), + Container( + padding: EdgeInsets.only(top: 16.0), + child: Text( "暂无数据", - style: new TextStyle( + style: TextStyle( color: Colors.grey, ), ), diff --git a/lib/views/items/collect_widget_list_item.dart b/lib/views/items/collect_widget_list_item.dart new file mode 100644 index 0000000..21bb303 --- /dev/null +++ b/lib/views/items/collect_widget_list_item.dart @@ -0,0 +1,112 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_star/flutter_star.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/app/style/shape/coupon_shape_border.dart'; +import 'package:flutter_unit/app/style/shape/techno_shape.dart'; +import 'package:flutter_unit/components/circle_image.dart'; +import 'package:flutter_unit/components/circle_text.dart'; +import 'package:flutter_unit/model/widget_model.dart'; + +class CollectWidgetListItem extends StatelessWidget { + final WidgetModel data; + + CollectWidgetListItem({this.data}); + + @override + Widget build(BuildContext context) { + return Material( + color: itemColor.withAlpha(66), + shape: TechnoShapeBorder(color: itemColor), + child: Container( + height: 95, + padding: EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 5), + child: Row( + children: [ + Wrap( + spacing: 5, + direction: Axis.vertical, + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + _buildLeading(), + ], + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildTitle(), + _buildSummary(), + StarScore( + star: Star( + emptyColor: Colors.white, + size: 12, + fillColor: itemColor), + score: data.lever, + ) + ], + ), + ), + ], + ), + ), + ); + } + + Widget _buildLeading() => Padding( + padding: const EdgeInsets.only(left: 5, right: 5), + child: data.image == null + ? Material( + color: Colors.transparent, + child: CircleText( + text: data.name, + size: 60, + color: itemColor, + ), + ) + : CircleImage( + image: data.image, + size: 60, + ), + ); + + Color get itemColor => Color(Cons.tabColors[data.family.index]); + + Widget _buildTitle() { + return Row( + children: [ +// SizedBox(width: 10), + Expanded( + child: Text(data.name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + shadows: [ + Shadow(color: Colors.white, offset: Offset(.3, .3)) + ])), + ), + ], + ); + } + + Widget _buildSummary() { + return Padding( + padding: const EdgeInsets.only(left: 0, bottom: 10, top: 5), + child: Container( + child: Text( + data.nameCN, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.grey[600], + fontSize: 14, + shadows: [Shadow(color: Colors.white, offset: Offset(.5, .5))]), + ), + ), + ); + } +} diff --git a/lib/views/items/techno_widget_list_item.dart b/lib/views/items/techno_widget_list_item.dart index 20bd20c..d53fb65 100644 --- a/lib/views/items/techno_widget_list_item.dart +++ b/lib/views/items/techno_widget_list_item.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_star/flutter_star.dart'; import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; import 'package:flutter_unit/app/style/shape/coupon_shape_border.dart'; import 'package:flutter_unit/app/style/shape/techno_shape.dart'; import 'package:flutter_unit/components/circle_image.dart'; @@ -13,86 +14,86 @@ class TechnoWidgetListItem extends StatelessWidget { TechnoWidgetListItem({this.data}); - @override Widget build(BuildContext context) { - return Material( + return Material( color: itemColor.withAlpha(66), - shape: TechnoShapeBorder( - color: itemColor - ), + shape: TechnoShapeBorder(color: itemColor), child: Container( - height: 95, - padding: EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 5), - child: Row( - children: [ - Wrap( - spacing: 5, - direction: Axis.vertical, - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - _buildLeading(), - StarScore( - star: Star(emptyColor: Colors.white, size: 12, fillColor: itemColor), - score: data.lever, - ) - ], + height: 95, + padding: EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 5), + child: Row( + children: [ + Wrap( + spacing: 5, + direction: Axis.vertical, + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + _buildLeading(), + StarScore( + star: Star( + emptyColor: Colors.white, size: 12, fillColor: itemColor), + score: data.lever, + ) + ], + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [_buildTitle(), _buildSummary()], ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [_buildTitle(), _buildSummary()], - ), - ), - ], - ), + ), + ], + ), ), ); } Widget _buildLeading() => Padding( - padding: const EdgeInsets.only(left: 5,right: 5), - child: Hero( - tag: "hero_widget_image_${data.name}", - child: data.image == null - ? Material( - color: Colors.transparent, - child: CircleText( - text: data.name, - size: 60, - color: itemColor, - ), - ) - : CircleImage( - image: data.image, - size: 55, - ), - ), - ); + padding: const EdgeInsets.only(left: 5, right: 5), + child: Hero( + tag: "hero_widget_image_${data.name}", + child: data.image == null + ? Material( + color: Colors.transparent, + child: CircleText( + text: data.name, + size: 60, + color: itemColor, + ), + ) + : CircleImage( + image: data.image, + size: 55, + ), + ), + ); Color get itemColor => Color(Cons.tabColors[data.family.index]); Widget _buildTitle() { - return Row( - children: [ - SizedBox(width: 10),Text(data.name, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - shadows: [ - Shadow(color: Colors.white, offset: Offset(.3, .3)) - ])), - ], + return Row( + children: [ + SizedBox(width: 10), + Expanded( + child: Text(data.name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + shadows: [ + Shadow(color: Colors.white, offset: Offset(.3, .3)) + ])), + ), + ], ); } Widget _buildSummary() { - return Padding( - padding: const EdgeInsets.only(left: 10, bottom: 10, top: 5), - child: Container( + return Container( + padding: EdgeInsets.only(left: 10), child: Text( //尾部摘要 data.info, @@ -103,7 +104,6 @@ class TechnoWidgetListItem extends StatelessWidget { fontSize: 14, shadows: [Shadow(color: Colors.white, offset: Offset(.5, .5))]), ), - ), ); } } diff --git a/lib/views/pages/act_page.dart b/lib/views/pages/act_page.dart deleted file mode 100644 index 1a2f911..0000000 --- a/lib/views/pages/act_page.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../empty_page.dart'; - -class ActPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - EmptyPage(), - Text("动态"), - ], - )); - } -} diff --git a/lib/views/pages/collect_page.dart b/lib/views/pages/collect_page.dart new file mode 100644 index 0000000..897c612 --- /dev/null +++ b/lib/views/pages/collect_page.dart @@ -0,0 +1,49 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/collect_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +import '../empty_page.dart'; + +class CollectPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('收藏集'),), + body: BlocBuilder( + builder: (_, state) { + return GridView.builder( + padding: EdgeInsets.all(10), + itemCount: state.widgets.length, + itemBuilder: (_, index) => Container( + child: GestureDetector( + onTap: () => _toDetailPage(context,state.widgets[index]), + child: CollectWidgetListItem( + data: state.widgets[index], + )), + ), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + childAspectRatio:1/0.5,), + ); + } + ), + ); + } + + _toDetailPage(BuildContext context,WidgetModel model){ + BlocProvider.of(context).add(FetchWidgetDetail(model)); + Navigator.pushNamed(context, Router.widget_detail); + } +} diff --git a/lib/views/pages/detail/widget_detail_page.dart b/lib/views/pages/detail/widget_detail_page.dart index f13a6af..1d71c23 100644 --- a/lib/views/pages/detail/widget_detail_page.dart +++ b/lib/views/pages/detail/widget_detail_page.dart @@ -2,14 +2,35 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_star/flutter_star.dart'; import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; import 'package:flutter_unit/blocs/detail/detail_state.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/widgets/widget_bloc.dart'; +import 'package:flutter_unit/blocs/widgets/widget_event.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; import 'package:flutter_unit/components/panel/panel.dart'; import 'package:flutter_unit/model/node_model.dart'; import 'package:flutter_unit/model/widget_model.dart'; import 'package:flutter_unit/views/widgets/widgets_map.dart'; -class WidgetDetailPage extends StatelessWidget { +class WidgetDetailPage extends StatefulWidget { + @override + _WidgetDetailPageState createState() => _WidgetDetailPageState(); +} + +class _WidgetDetailPageState extends State { + List stack; + + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { @@ -19,15 +40,33 @@ class WidgetDetailPage extends StatelessWidget { backgroundColor: Color(colors[state.widgetModel.family.index]), title: Text(state.widgetModel.name), actions: [ - Padding( - padding: const EdgeInsets.only(right: 20.0), - child: Icon(Icons.star_border), + FeedbackWidget( + onPressed: () async { + BlocProvider.of(context).add(ToggleCollectEvent( + id: state.widgetModel.id, + isCollect: !state.widgetModel.collected)); +// BlocProvider.of(context) +// .add(LoadWidget(state.widgetModel.family)); + }, + child: BlocBuilder(builder: (_, s) { +// print(s.widgets.contains(state.widgetModel)); + return Padding( + padding: const EdgeInsets.only(right: 20.0), + child: Icon( + s.widgets.contains(state.widgetModel) + ? TolyIcon.icon_star_ok + : TolyIcon.icon_star_add, + size: 25, + ), + ); + }), ) ], ), body: SingleChildScrollView( child: Container( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ @@ -36,6 +75,27 @@ class WidgetDetailPage extends StatelessWidget { ], ), Divider(), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 15, right: 5), + child: Icon( + Icons.link, + color: Colors.blue, + ), + ), + Text( + '相关组件', + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 16), + ), + ], + ), + _buildLinkTo( + context, + state.links, + ), + Divider(), _buildNodes(state.nodes, state.widgetModel.name) ], ), @@ -49,7 +109,6 @@ class WidgetDetailPage extends StatelessWidget { final List colors = Cons.tabColors; - // 构建上部左侧介绍 Widget _buildLeft(WidgetModel model) => Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -72,7 +131,6 @@ class WidgetDetailPage extends StatelessWidget { ), ); - // 构建上部右侧图片 Widget _buildRight(WidgetModel model) => Column( mainAxisSize: MainAxisSize.min, children: [ @@ -84,7 +142,9 @@ class WidgetDetailPage extends StatelessWidget { tag: "hero_widget_image_${model.name}", child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(8)), - child: model.image==null?Image.asset('assets/images/caver.jpeg'): Image(image: model.image))), + child: model.image == null + ? Image.asset('assets/images/caver.jpeg') + : Image(image: model.image))), ), ), StarScore( @@ -94,16 +154,53 @@ class WidgetDetailPage extends StatelessWidget { ], ); - //构建底部 元素 - Widget _buildNodes(List nodes, String name) => Column( + Widget _buildNodes(List nodes, String name) { + var globalState = BlocProvider.of(context).state; + + return Column( children: nodes .asMap() .keys .map((i) => NodePanel( + codeStyle: Cons.codeThemeSupport.keys.toList()[globalState.codeStyleIndex], + codeFamily: 'Inconsolata', text: nodes[i].name, subText: nodes[i].subtitle, code: nodes[i].code, show: WidgetsMap.map(name)[i], )) .toList()); + } + + _buildLinkTo(BuildContext context, List links) { + if (links == null || links.isEmpty) { + return Padding( + padding: EdgeInsets.only(left: 10), + child: Chip( + backgroundColor: Colors.grey.withAlpha(120), + labelStyle: TextStyle(fontSize: 12, color: Colors.white), + label: Text('暂无链接组件'), + )); + } else { + return Padding( + padding: const EdgeInsets.only(left: 10.0, top: 10), + child: Wrap( + spacing: 5, + children: links + .map((e) => ActionChip( + onPressed: () { + BlocProvider.of(context) + .add(FetchWidgetDetail(e)); + }, + elevation: 3, + shadowColor: Color(colors[e.family.index]), + backgroundColor: Colors.blue, + labelStyle: TextStyle(fontSize: 12, color: Colors.white), + label: Text('${e.name}'), + )) + .toList(), + ), + ); + } + } } diff --git a/lib/views/pages/home_drawer.dart b/lib/views/pages/home_drawer.dart deleted file mode 100644 index 9348dd6..0000000 --- a/lib/views/pages/home_drawer.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_unit/blocs/global/global_bloc.dart'; - -/// create by 张风捷特烈 on 2020-03-26 -/// contact me by email 1981462002@qq.com -/// 说明: - -class HomeDrawer extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Drawer( - elevation: 3, - child: _buildChild(), - ); - } - - Widget _buildChild() => BlocBuilder( - builder: (_, state) => Container( - color:state.color.withAlpha(55), - child: ListView( - padding: EdgeInsets.zero, - children: const [ - DrawerHeader( - padding: EdgeInsets.only(top: 10,left: 15), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.only( - bottomRight:Radius.circular(60), -// bottomLeft:Radius.circular(40) - ), - image: DecorationImage( - image: AssetImage('assets/images/caver.jpeg'), - fit: BoxFit.cover), - ), - child: Text( - 'Flutter Unit', - style: TextStyle(fontSize: 24, color: Colors.white, shadows: [ - Shadow(color: Colors.black, offset: Offset(1, 1), blurRadius: 3) - ]), - ), - ), - ListTile( - leading: Icon( - Icons.star, - color: Colors.blue, - ), - title: Text('我的收藏'), - ), - ListTile( - leading: Icon( - Icons.palette, - color: Colors.orangeAccent, - ), - title: Text('我的绘画'), - ), - ListTile( - leading: Icon( - Icons.insert_drive_file, - color: Colors.green, - ), - title: Text('我的文件'), - ), - ], - ), - )); -} \ No newline at end of file diff --git a/lib/views/pages/home_page.dart b/lib/views/pages/home_page.dart index 6742216..fb33467 100644 --- a/lib/views/pages/home_page.dart +++ b/lib/views/pages/home_page.dart @@ -6,15 +6,18 @@ import 'package:flutter_unit/app/router.dart'; import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; import 'package:flutter_unit/blocs/detail/detail_event.dart'; import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; import 'package:flutter_unit/blocs/widgets/widget_bloc.dart'; import 'package:flutter_unit/blocs/widgets/widget_event.dart'; import 'package:flutter_unit/blocs/widgets/widget_state.dart'; import 'package:flutter_unit/components/toly_app_bar.dart'; +import 'package:flutter_unit/model/widget_model.dart'; import 'package:flutter_unit/views/empty_page.dart'; import 'package:flutter_unit/views/items/coupon_widget_list_item.dart'; import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; import '../home/home_light_drawer.dart'; -import 'home_drawer.dart'; +import 'setting/home_drawer.dart'; class HomePage extends StatefulWidget { @override @@ -23,42 +26,28 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { ScrollController _ctrl; - double limitY = 35; + double _limitY = 35; @override void initState() { - _ctrl = ScrollController() - ..addListener(() { - if (_ctrl.offset < limitY * 4) { - var offsetY = kToolbarHeight * 2 - 20 - _ctrl.offset / 4; - BlocProvider.of(context).add(UpdateAppBarHeight(offsetY)); - } - }); + _ctrl = ScrollController()..addListener(_updateAppBarHeight); super.initState(); } @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (_, state) => Scaffold( - appBar: TolyAppBar( - preferredSize: Size.fromHeight(state.height), - onItemClick: (index, e) { - if (_ctrl.hasClients) _ctrl.jumpTo(0); - BlocProvider.of(context) - .add(EventSwitchColor(e)); - BlocProvider.of(context) - .add(LoadWidget(Convert.toFamily(index))); - }, - ), - body: Stack( - children: [BackGround(), _buildContent(context)], - ), - drawer: HomeDrawer(), - //左滑页 - endDrawer: HomeRightDrawer(), //右滑页 - )); - } + Widget build(BuildContext context) => BlocBuilder( + builder: (_, state) => Scaffold( + appBar: TolyAppBar( + preferredSize: Size.fromHeight(state.height), + onItemClick: _switchTab, + ), + body: Stack( + children: [ + if (state.showBackGround) BackGround(), + _buildContent(context) + ], + ), + )); Widget _buildContent(BuildContext context) => BlocBuilder(builder: (_, state) { @@ -69,34 +58,65 @@ class _HomePageState extends State { controller: _ctrl, itemBuilder: (_, index) => Container( margin: EdgeInsets.symmetric(horizontal: 15, vertical: 5), - child: InkWell( - onTap: () { - BlocProvider.of(context) - .add(ToWidgetDetail(items[index])); - Navigator.pushNamed(context, Router.widget_detail); - }, - child: TechnoWidgetListItem( - data: items[index], - )), + child: GestureDetector( + onTap: () => _toDetailPage(items[index]), + child: _mapItemByType(items[index])), ), separatorBuilder: (_, index) => Container(), itemCount: items.length); } - if(state is WidgetsLoadFailed){ - return Container(child: Text('加载数据异常'),); + if (state is WidgetsLoadFailed) { + return Container( + child: Text('加载数据异常'), + ); } return Container(); }); + + Widget _mapItemByType(WidgetModel model) { + var index = BlocProvider.of(context).state.itemStyleIndex; + switch (index) { + case 0: + return TechnoWidgetListItem( + data: model, + ); + case 1: + return CouponWidgetListItem( + data: model, + ); + } + return TechnoWidgetListItem( + data: model, + ); + } + + _updateAppBarHeight() { + if (_ctrl.offset < _limitY * 4) { + var offsetY = kToolbarHeight * 2 - 20 - _ctrl.offset / 4; + BlocProvider.of(context).add(UpdateAppBarHeight(offsetY)); + } + } + + _switchTab(int index, Color color) { + if (_ctrl.hasClients) _ctrl.jumpTo(0); + BlocProvider.of(context).add(EventSwitchHomeColor(color)); + BlocProvider.of(context) + .add(LoadWidget(Convert.toFamily(index))); + } + + _toDetailPage(WidgetModel model) { + BlocProvider.of(context).add(FetchWidgetDetail(model)); + Navigator.pushNamed(context, Router.widget_detail); + } } class BackGround extends StatelessWidget { @override Widget build(BuildContext context) { return Opacity( - opacity: 0.1, + opacity: 0.05, child: Container( decoration: BoxDecoration( -// color: Colors.orangeAccent.withAlpha(44), image: DecorationImage( image: AssetImage('assets/images/sabar.jpg'), fit: BoxFit.cover), diff --git a/lib/views/pages/search/app_search_bar.dart b/lib/views/pages/search/app_search_bar.dart index 6b3001d..d3fadbc 100644 --- a/lib/views/pages/search/app_search_bar.dart +++ b/lib/views/pages/search/app_search_bar.dart @@ -2,9 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_unit/blocs/search/search_bloc.dart'; import 'package:flutter_unit/blocs/search/search_event.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; class AppSearchBar extends StatefulWidget { + + @override _AppSearchBarState createState() => _AppSearchBarState(); } @@ -33,11 +36,11 @@ class _AppSearchBarState extends State { hintStyle: TextStyle(fontSize: 14)//提示样式 ), onChanged: (str) => BlocProvider.of(context) - .add(EventTextChanged(str)), + .add(EventTextChanged(args:SearchArgs(name: str,stars: [1,2,3,4,5]))), onSubmitted: (str) {//提交后 FocusScope.of(context).requestFocus(FocusNode()); //收起键盘 - _controller.clear(); +// _controller.clear(); }, )); diff --git a/lib/views/pages/search/error_page.dart b/lib/views/pages/search/error_page.dart index 68fea77..b90fd94 100644 --- a/lib/views/pages/search/error_page.dart +++ b/lib/views/pages/search/error_page.dart @@ -5,8 +5,9 @@ class ErrorPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Center(child: Container( - alignment: FractionalOffset.center, + return Container( + height: 300, + alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, @@ -24,6 +25,6 @@ class ErrorPage extends StatelessWidget { ) ], ), - ),); + ); } } diff --git a/lib/views/pages/search/loading_page.dart b/lib/views/pages/search/loading_page.dart index 2998a0e..f092842 100644 --- a/lib/views/pages/search/loading_page.dart +++ b/lib/views/pages/search/loading_page.dart @@ -6,7 +6,9 @@ class LoadingPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Center( + return Container( + height: 300, + alignment: Alignment.center, child: CircularProgressIndicator(backgroundColor: Colors.blue,valueColor:AlwaysStoppedAnimation(Colors.orangeAccent) ,), ); } diff --git a/lib/views/pages/search/not_search_page.dart b/lib/views/pages/search/not_search_page.dart index d0130ac..cc4fd9e 100644 --- a/lib/views/pages/search/not_search_page.dart +++ b/lib/views/pages/search/not_search_page.dart @@ -5,8 +5,9 @@ class NotSearchPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Center(child: Container( - alignment: FractionalOffset.center, + return Container( + height: 300, + alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, @@ -15,7 +16,7 @@ class NotSearchPage extends StatelessWidget { Container( padding: EdgeInsets.only(top: 16.0), child: Text( - "哥们,搜点啥...,≧◔◡◔≦", + "哥们,搜点啥...≧◔◡◔≦", style: TextStyle( fontSize: 20, color: Colors.blue, @@ -24,6 +25,6 @@ class NotSearchPage extends StatelessWidget { ) ], ), - ),); + ); } } diff --git a/lib/views/pages/search/start_filter.dart b/lib/views/pages/search/start_filter.dart new file mode 100644 index 0000000..bbdfdf3 --- /dev/null +++ b/lib/views/pages/search/start_filter.dart @@ -0,0 +1,113 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/blocs/search/search_bloc.dart'; +import 'package:flutter_unit/blocs/search/search_event.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; + +/// create by 张风捷特烈 on 2020-04-07 +/// contact me by email 1981462002@qq.com +/// 说明: + +typedef BoolWidgetBuilder = Widget Function(BuildContext context, bool selected); + +class MultiChipFilter extends StatefulWidget { + final List data; + final BoolWidgetBuilder labelBuilder; + final IndexedWidgetBuilder avatarBuilder; + final Function(List) onChange; + + MultiChipFilter({@required this.data,@required this.labelBuilder,this.avatarBuilder,@required this.onChange}); + + @override + _MultiChipFilterState createState() => _MultiChipFilterState(); +} + +class _MultiChipFilterState extends State> { + List _selected = []; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: widget.data.map((e) => + _buildChild(context,widget.data.indexOf(e))).toList(), + ); + } + + Widget _buildChild(BuildContext context,int index) { + bool selected = _selected.contains(index); + return FilterChip( + selectedColor: Colors.orange.withAlpha(55), + labelPadding: EdgeInsets.only(left: 5,right: 5), + selectedShadowColor: Colors.blue, + shadowColor: Colors.orangeAccent, + pressElevation: 5, + elevation: 3, + avatar: widget.avatarBuilder==null?null:widget.avatarBuilder(context,index), + label: widget.labelBuilder(context,selected), + selected: selected, + onSelected: (bool value) { + setState(() { + if (value) { + _selected.add(index); + } else { + _selected.removeWhere((i) => i == index); + } + if(widget.onChange!=null) widget.onChange(_selected); + }); + }, + ); + } +} + +//class StartFilter extends StatefulWidget { +// @override +// _StartFilterState createState() => _StartFilterState(); +//} +// +//class _StartFilterState extends State { +// List data = [1,2,3,4,5]; +// List _selected = []; +// +// @override +// Widget build(BuildContext context) { +// return Row( +// mainAxisAlignment: MainAxisAlignment.spaceEvenly, +// children: data.map((e) => +// _buildChild(e)).toList(), +// ); +// } +// +// Widget _buildChild(int e) { +// bool selected = _selected.contains(e); +// return FilterChip( +// selectedColor: Colors.orange.withAlpha(55), +// labelPadding: EdgeInsets.only(left: 5,right: 5), +// selectedShadowColor: Colors.blue, +// shadowColor: Colors.orangeAccent, +// pressElevation: 5, +// elevation: 3, +// avatar: CircleAvatar(child: Text((data.indexOf(e)+1).toString())), +// label: Icon(Icons.star,color: selected?Colors.blue:Colors.grey,size: 18,), +// selected: selected, +// onSelected: (bool value) { +// setState(() { +// if (value) { +// _selected.add(e); +// } else { +// _selected.removeWhere((name) => name == e); +// } +// var args = _selected.map((e)=>e).toList(); +// if(args.length<5){ +// args.addAll(List.generate(5-args.length, (e)=>-1)); +// } +// BlocProvider.of(context) +// .add(EventTextChanged(args:SearchArgs(name: '',stars: args))); +// }); +// }, +// ); +// } +//} + + + diff --git a/lib/views/pages/serach_page.dart b/lib/views/pages/serach_page.dart index fd06d7b..b5d6f29 100644 --- a/lib/views/pages/serach_page.dart +++ b/lib/views/pages/serach_page.dart @@ -1,12 +1,23 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; import 'package:flutter_unit/blocs/search/search_bloc.dart'; +import 'package:flutter_unit/blocs/search/search_event.dart'; import 'package:flutter_unit/blocs/search/search_state.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; import 'package:flutter_unit/views/pages/search/app_search_bar.dart'; import 'package:flutter_unit/views/pages/search/error_page.dart'; import 'package:flutter_unit/views/pages/search/loading_page.dart'; import 'package:flutter_unit/views/pages/search/not_search_page.dart'; +import 'package:flutter_unit/views/pages/search/start_filter.dart'; import '../empty_page.dart'; @@ -19,25 +30,107 @@ class _SearchPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - actions: [ - Padding( - padding: const EdgeInsets.only(right: 15.0), - child: Icon(TolyIcon.icon_star_add), - ) - ], - title: AppSearchBar(), + body: WillPopScope( + onWillPop: () async { + //返回时 情空搜索 + BlocProvider.of(context) + .add(EventTextChanged(args: SearchArgs())); + return true; + }, + child: CustomScrollView( + slivers: [ + _buildSliverAppBar(), + SliverToBoxAdapter(child: _buildStarFilter()), + BlocBuilder(builder: (_, state) => _buildBodyByState(state)) + ], + ), ), - body: BlocBuilder( - builder: (_, state) => _buildBodyByState(state)), ); } - _buildBodyByState(SearchState state) { - if (state is SearchStateNoSearch) return NotSearchPage(); - if (state is SearchStateLoading) return LoadingPage(); - if (state is SearchStateError) return ErrorPage(); -// if (state is SearchStateSuccess) return FillPage(state.result); - if (state is SearchStateEmpty) return EmptyPage(); + Widget _buildSliverAppBar() { + return SliverAppBar( + pinned: true, + title: AppSearchBar(), + actions: [ + Padding( + padding: const EdgeInsets.only(right: 15.0), + child: Icon(TolyIcon.icon_sound), + ) + ], + ); + } + + Widget _buildStarFilter() => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 10.0, left: 20, bottom: 5), + child: Wrap( + spacing: 5, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Circle( + radius: 5, + color: Colors.orange, + ), + Text( + '星级查询', + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold), + ), + ], + ), + ), + MultiChipFilter( + data: [1, 2, 3, 4, 5], + avatarBuilder: (_, index) => + CircleAvatar(child: Text((index + 1).toString())), + labelBuilder: (_, selected) => Icon( + Icons.star, + color: selected ? Colors.blue : Colors.grey, + size: 18, + ), + onChange: _doSelectStart, + ), + Divider() + ], + ); + + Widget _buildBodyByState(SearchState state) { + if (state is SearchStateNoSearch) return SliverToBoxAdapter(child: NotSearchPage(),); + if (state is SearchStateLoading) return SliverToBoxAdapter(child: LoadingPage()); + if (state is SearchStateError) return SliverToBoxAdapter(child: ErrorPage()); + if (state is SearchStateSuccess) return _buildSliverList(state.result); + if (state is SearchStateEmpty) return SliverToBoxAdapter(child: EmptyPage()); + return NotSearchPage(); + } + + Widget _buildSliverList(List models) => SliverList( + delegate: SliverChildBuilderDelegate( + (_, int index) => Container( + margin: EdgeInsets.symmetric(horizontal: 15, vertical: 5), + child: InkWell( + onTap: () => _toDetailPage(models[index]), + child: TechnoWidgetListItem( + data: models[index], + ))), + childCount: models.length), + ); + + _doSelectStart(List select) { + var temp = select.map((e)=>e+1).toList(); + if (temp.length < 5) { + temp.addAll(List.generate(5 - temp.length, (e) => -1)); + } + BlocProvider.of(context) + .add(EventTextChanged(args: SearchArgs(name: '', stars: temp))); + } + + _toDetailPage(WidgetModel model) { + BlocProvider.of(context).add(FetchWidgetDetail(model)); +// BlocProvider.of(context).add(EventSetCollect(collect:model.collected)); + Navigator.pushNamed(context, Router.widget_detail); } } diff --git a/lib/views/pages/setting/code_style_setting.dart b/lib/views/pages/setting/code_style_setting.dart new file mode 100644 index 0000000..5516e26 --- /dev/null +++ b/lib/views/pages/setting/code_style_setting.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/code/code_panel.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; + +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +class CodeStyleSettingPage extends StatelessWidget { + final code = """ +const String _kCounty = 'China'; + +class Hello { + final String name;//言语 + final String county;//国家 + final int age;//年龄 + + Hello({ + this.name = "张风捷特烈", + this.age = 26, + this.county = _kCounty + }); +}"""; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('代码高亮样式'), + ), + body: BlocBuilder( + builder: (_, state) => _buildFontCell(context, + Cons.codeThemeSupport.keys.toList(), state.codeStyleIndex)), + ); + } + + Widget _buildFontCell( + BuildContext context, List styles, int index) { + return ListView.builder( + itemCount: styles.length, + itemBuilder: (_ctx, i) => FeedbackWidget( + a: 0.95, + duration: Duration(milliseconds: 200), + onPressed: (){ + BlocProvider.of(context).add(EventSwitchCoderTheme(i)); + }, + child: Stack( + fit: StackFit.passthrough, + children: [ + Card( + margin: EdgeInsets.all(10), + child: CodeWidget( + code: code, + style: styles[i], + ), + ), + + Positioned( + right: 20, + bottom: 20, + child: Text(Cons.codeThemeSupport.values.toList()[i],style: TextStyle( + fontSize: 14, + color: styles[i].stringStyle.color, + shadows: [Shadow( + color: Colors.white, + offset: Offset(.5,.5), + blurRadius: 1 + ),] + ),), + ), + + if(index == i) + Positioned( + right: 20, + top: 20, + child: Circle(radius: 10, + color: Theme.of(context).primaryColor, + child: Icon(Icons.check,color:Colors.white,size: 15,),), + ) + ], + ), + )); + } +} diff --git a/lib/views/pages/setting/font_setting.dart b/lib/views/pages/setting/font_setting.dart new file mode 100644 index 0000000..6845f3a --- /dev/null +++ b/lib/views/pages/setting/font_setting.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; + +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +class FontSettingPage extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('字体设置 - font setting'), + ), + body: BlocBuilder( + builder: (_, state) => _buildFontCell( + context, Cons.fontFamilySupport, state.fontFamily)), + ); + } + + Widget _buildFontCell( + BuildContext context, List fontFamilySupport, String fontFamily) { + return GridView.count( + padding: EdgeInsets.only(top: 20, left: 10, right: 10), + shrinkWrap: true, + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + childAspectRatio: 1.5, + children: fontFamilySupport + .map((e) => FeedbackWidget( + a: 0.95, + duration: Duration(milliseconds: 200), + onPressed: () { + BlocProvider.of(context) + .add(EventSwitchFontFamily(e)); + }, + child: Card( + child: GridTile( + header: Container( + padding: EdgeInsets.only(left: 10, right: 5), + height: 30, + color: fontFamily == e + ? Colors.blue.withAlpha(88) + : Colors.grey.withAlpha(88), + child: Row( + children: [ + Text(e, + style: TextStyle( + color: Colors.black, + fontFamily: e, + )), + Spacer(), + if (fontFamily == e) Circle(color: Theme.of(context).primaryColor,) + ], + ), + ), + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient(colors: [ + Colors.blueAccent.withAlpha(22), + Colors.blueAccent.withAlpha(22), + Theme.of(context).primaryColor.withAlpha(88) + ])), + alignment: Alignment(0, 0.4), + child: Text( + '张风捷特烈\n@toly1994', + style: TextStyle(fontFamily: e, fontSize: 16), + )), + ), + ))) + .toList(), + ); + } +} diff --git a/lib/views/pages/setting/home_drawer.dart b/lib/views/pages/setting/home_drawer.dart new file mode 100644 index 0000000..e57c3cd --- /dev/null +++ b/lib/views/pages/setting/home_drawer.dart @@ -0,0 +1,223 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; + +/// create by 张风捷特烈 on 2020-03-26 +/// contact me by email 1981462002@qq.com +/// 说明: + +class HomeDrawer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Drawer( + elevation: 3, + child: _buildChild(context), + ); + } + + Widget _buildChild(BuildContext context) => + BlocBuilder( + builder: (_, state) => Container( + color: state.color.withAlpha(33), + child: ListView( + padding: EdgeInsets.zero, + children: [ + _buildDrawerHeader(state), + ListTile( + leading: Icon( + TolyIcon.icon_them, + color: Theme.of(context).primaryColor, + ), + trailing: _nextIcon(context), + title: Text('我的主题'), + onTap: () { + Navigator.of(context).pushNamed(Router.setting); + }, + ), + ListTile( + leading: Icon( + TolyIcon.icon_star, + color: Theme.of(context).primaryColor, + ), + title: Text('我的收藏'), + trailing: _nextIcon(context), + onTap: () { + Navigator.of(context).pushNamed(Router.collect); + }, + ), + Divider( + height: 1, + ), + _buildFlutterUnit(context), + ListTile( + leading: Icon( + TolyIcon.icon_code, + color: Theme.of(context).primaryColor, + ), + title: Text('Dart 手册'), + trailing: _nextIcon(context), + onTap: () {}, + ), + Divider( + height: 1, + ), + ListTile( + leading: Icon( + TolyIcon.icon_layout, + color: Theme.of(context).primaryColor, + ), + title: Text('数据统计'), + trailing: _nextIcon(context), + onTap: () {}, + ), + ListTile( + leading: Icon( + TolyIcon.icon_kafei, + color: Theme.of(context).primaryColor, + ), + title: Text('关于应用'), + trailing: _nextIcon(context), + onTap: () {}, + ), + ], + ), + )); + + Widget _buildFlutterUnit(BuildContext context) => ExpansionTile( + backgroundColor: Colors.white70, + leading: Icon( + Icons.extension, + color: Theme.of(context).primaryColor, + ), + title: Text('Flutter 集录'), + children: [ + ListTile( + leading: Icon( + TolyIcon.icon_tag, + color: Theme.of(context).primaryColor, + ), + title: Text('属性集录'), + trailing: _nextIcon(context), + onTap: () { + Navigator.of(context).pushNamed(Router.attr); + }, + ), + ListTile( + leading: Icon( + Icons.palette, + color: Theme.of(context).primaryColor, + ), + title: Text('绘画集录'), + trailing: _nextIcon(context), + onTap: () { + Navigator.of(context).pushNamed(Router.paint); + }, + ), + ListTile( + leading: Icon( + Icons.widgets, + color: Theme.of(context).primaryColor, + ), + title: Text('布局集录'), + trailing: _nextIcon(context), + onTap: () { + Navigator.of(context).pushNamed(Router.layout); + }, + ), + ListTile( + leading: Icon( + TolyIcon.icon_bug, + color: Theme.of(context).primaryColor, + ), + trailing: _nextIcon(context), + title: Text('bug 集录'), + onTap: () { + Navigator.of(context).pushNamed(Router.bug); + }, + ), + ], + ); + + Widget _buildDrawerHeader(GlobalState state) => DrawerHeader( + padding: EdgeInsets.only(top: 10, left: 15), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/wy_300x200_filter.jpg'), + fit: BoxFit.cover), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Wrap( + spacing: 10, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + FlutterLogo( + colors: Colors.orange, + size: 35, + ), + Text( + 'Flutter Unit', + style: TextStyle(fontSize: 24, color: Colors.white, shadows: [ + Shadow( + color: Colors.black, + offset: Offset(1, 1), + blurRadius: 3) + ]), + ), + ], + ), + SizedBox( + height: 15, + ), + Text( + 'The Unity Of Flutter, The Unity Of Coder.', + style: TextStyle(fontSize: 15, color: Colors.white, shadows: [ + Shadow( + color: state.color, offset: Offset(.5, .5), blurRadius: 1) + ]), + ), + SizedBox( + height: 5, + ), + Text( + 'Flutter的联合,编程者的联合。', + style: TextStyle(fontSize: 15, color: Colors.white, shadows: [ + Shadow( + color: state.color, offset: Offset(.5, .5), blurRadius: 1) + ]), + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Spacer( + flex: 5, + ), + Text( + '—— 张风捷特烈', + style: TextStyle(fontSize: 15, color: Colors.white, shadows: [ + Shadow( + color: Colors.orangeAccent, + offset: Offset(.5, .5), + blurRadius: 1) + ]), + ), + Spacer( + flex: 1, + ), + ], + ), + ], + ), + ); + + Widget _nextIcon(BuildContext context) => + Icon(Icons.chevron_right, color: Theme.of(context).primaryColor); +} diff --git a/lib/views/pages/setting/item_style_setting.dart b/lib/views/pages/setting/item_style_setting.dart new file mode 100644 index 0000000..92bd13e --- /dev/null +++ b/lib/views/pages/setting/item_style_setting.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/enums.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/code/code_panel.dart'; +import 'package:flutter_unit/components/code/highlighter_style.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/coupon_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +final data = WidgetModel( + name: 'Container', + nameCN: '容器组件', + lever: 5, + family: WidgetFamily.statelessWidget, + info: '用于容纳单个子组件的容器组件。集成了若干个单子组件的功能,如内外边距、形变、装饰、约束等...'); + +final data2 = WidgetModel( + name: 'Container ', + nameCN: '容器组件', + lever: 5, + family: WidgetFamily.statelessWidget, + info: '用于容纳单个子组件的容器组件。集成了若干个单子组件的功能,如内外边距、形变、装饰、约束等...'); + +class ItemStyleSettingPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('item样式设置'), + ), + body: BlocBuilder( + builder: (_, state) => _buildFontCell(context, state.itemStyleIndex)), + ); + } + + final items = [ + TechnoWidgetListItem( + data: data, + ), + CouponWidgetListItem( + data: data2, + ) + ]; + + Widget _buildFontCell(BuildContext context, int index) { + return ListView.builder( + itemCount: items.length, + itemBuilder: (_, i) => Padding( + padding: EdgeInsets.only(left: 20, top: 20, right: 20), + child: FeedbackWidget( + a: 0.95, + duration: Duration(milliseconds: 200), + onPressed: () { + BlocProvider.of(context) + .add(EventSwitchCoderTheme(i)); + }, + child: Stack( + children: [ + items[i], + if (index == i) + Positioned( + left: 15, + top: 15, + child: Circle( + color: Theme.of(context).primaryColor, + radius: 10, + child: Icon( + Icons.check, + color: Colors.white, + size: 15, + ), + ), + ) + ], + )))); + } +} diff --git a/lib/views/pages/setting/setting_page.dart b/lib/views/pages/setting/setting_page.dart new file mode 100644 index 0000000..f546630 --- /dev/null +++ b/lib/views/pages/setting/setting_page.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/app/style/TolyIcon.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; + +class SettingPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('主题设置'), + ), + body: ListView( + children: [ + ListTile( + leading: Icon( + Icons.palette, + color: Theme.of(context).primaryColor, + ), + title: Text('主题色设置'), + trailing: _nextIcon(context), + onTap: () => Navigator.of(context).pushNamed(Router.theme_color_setting), + ), + Divider(), + ListTile( + leading: Icon( + Icons.translate, + color: Theme.of(context).primaryColor, + ), + title: Text('字体设置'), + trailing: _nextIcon(context), + onTap: () => Navigator.of(context).pushNamed(Router.font_setting), + ), + Divider(), + ListTile( + leading: Icon( + TolyIcon.icon_item, + color: Theme.of(context).primaryColor, + ), + title: Text('item样式设置'), + trailing: _nextIcon(context), + onTap: () => Navigator.of(context).pushNamed(Router.item_style_setting), + ), + Divider(), + ListTile( + leading: Icon( + TolyIcon.icon_code, + color: Theme.of(context).primaryColor, + ), + title: Text('代码高亮样式'), + trailing: _nextIcon(context), + onTap: () => Navigator.of(context).pushNamed(Router.code_style_setting), + ), + Divider(), + _buildShowBg(context), + ], + ), + ); + } + + Widget _buildShowBg(BuildContext context) => + BlocBuilder( + builder: (_, state) => SwitchListTile( + value: state.showBackGround, + secondary: Icon( + TolyIcon.icon_background, + color: Theme.of(context).primaryColor, + ), + title: Text('显示背景'), + onChanged: (show) { + BlocProvider.of(context) + .add(EventSwitchShowBg(show)); + }, + )); + + Widget _nextIcon(BuildContext context) => + Icon(Icons.chevron_right, color: Theme.of(context).primaryColor); +} diff --git a/lib/views/pages/setting/theme_color_setting.dart b/lib/views/pages/setting/theme_color_setting.dart new file mode 100644 index 0000000..21487f9 --- /dev/null +++ b/lib/views/pages/setting/theme_color_setting.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_event.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/components/feedback_widget.dart'; +import 'package:flutter_unit/components/panel/circle.dart'; + +/// create by 张风捷特烈 on 2020-04-10 +/// contact me by email 1981462002@qq.com +/// 说明: + +class ThemeColorSettingPage extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('主题色设置'), + ), + body: BlocBuilder( + builder: (_, state) => _buildFontCell( + context, Cons.themeColorSupport.keys.toList(), state.themeColor)), + ); + } + + Widget _buildFontCell( + BuildContext context, List themeColorSupport, MaterialColor color) { + return GridView.count( + padding: EdgeInsets.only(top: 20, left: 10, right: 10), + shrinkWrap: true, + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + childAspectRatio: 1.5, + children: themeColorSupport + .map((e) => FeedbackWidget( + a: 0.95, + duration: Duration(milliseconds: 200), + onPressed: () => BlocProvider.of(context).add(EventSwitchThemeColor(e)), + child: GridTile( + header: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)), + color: color == e + ? Colors.blue.withAlpha(88): + Colors.grey.withAlpha(55), + ), + padding: EdgeInsets.only(left: 10, right: 5), + height: 30, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Spacer(), + Text(colorString(e), + style: TextStyle( + color: Colors.white, + )), + Spacer(), + if (color == e) Padding( + padding: const EdgeInsets.only(right:8.0), + child: Circle(color: Colors.white,radius: 7,), + ) + ], + ), + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10)), + gradient: LinearGradient(colors: [ + e[50], + e[100], + e[200], + e[300], + e[400], + e[500], + e[600], + e[700], + e[800], + e[900], + ])), + alignment: Alignment(0,0.35), + child: Text( + Cons.themeColorSupport [e], + style: TextStyle(fontSize: 18,color: Colors.white,fontWeight: FontWeight.bold), + )), + ))) + .toList(), + ); + } + + String colorString(Color color) => + "#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}"; +} diff --git a/lib/views/pages/unit/attr_unit_page.dart b/lib/views/pages/unit/attr_unit_page.dart new file mode 100644 index 0000000..428606d --- /dev/null +++ b/lib/views/pages/unit/attr_unit_page.dart @@ -0,0 +1,25 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/collect_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +import '../../empty_page.dart'; + +class AttrUnitPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('属性集录'),), + body: Container(), + ); + } +} diff --git a/lib/views/pages/unit/bug_unit_page.dart b/lib/views/pages/unit/bug_unit_page.dart new file mode 100644 index 0000000..70e9ade --- /dev/null +++ b/lib/views/pages/unit/bug_unit_page.dart @@ -0,0 +1,25 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/collect_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +import '../../empty_page.dart'; + +class BugUnitPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('bug 集录'),), + body: Container(), + ); + } +} diff --git a/lib/views/pages/unit/layout_unit_page.dart b/lib/views/pages/unit/layout_unit_page.dart new file mode 100644 index 0000000..8116564 --- /dev/null +++ b/lib/views/pages/unit/layout_unit_page.dart @@ -0,0 +1,26 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/collect_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +import '../../empty_page.dart'; + +class LayoutUnitPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('布局集录'),), + body: Container(), + ); + } + +} diff --git a/lib/views/pages/unit/paint_unit_page.dart b/lib/views/pages/unit/paint_unit_page.dart new file mode 100644 index 0000000..7f171fd --- /dev/null +++ b/lib/views/pages/unit/paint_unit_page.dart @@ -0,0 +1,26 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; +import 'package:flutter_unit/blocs/collect/collect_state.dart'; +import 'package:flutter_unit/blocs/detail/detail_bloc.dart'; +import 'package:flutter_unit/blocs/detail/detail_event.dart'; +import 'package:flutter_unit/model/widget_model.dart'; +import 'package:flutter_unit/views/items/collect_widget_list_item.dart'; +import 'package:flutter_unit/views/items/techno_widget_list_item.dart'; + +import '../../empty_page.dart'; + +class PaintUnitPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('绘制集录'),), + body: Container(), + ); + } + +} diff --git a/lib/views/pages/unit_navigation.dart b/lib/views/pages/unit_navigation.dart index f524936..08f407c 100644 --- a/lib/views/pages/unit_navigation.dart +++ b/lib/views/pages/unit_navigation.dart @@ -3,9 +3,17 @@ import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_unit/app/res/cons.dart'; import 'package:flutter_unit/app/router.dart'; +import 'package:flutter_unit/blocs/collect/collect_bloc.dart'; +import 'package:flutter_unit/blocs/collect/collect_event.dart'; import 'package:flutter_unit/blocs/global/global_bloc.dart'; +import 'package:flutter_unit/blocs/global/global_state.dart'; +import 'package:flutter_unit/blocs/search/search_bloc.dart'; +import 'package:flutter_unit/blocs/search/search_event.dart'; +import 'package:flutter_unit/database/widget_dao.dart'; +import 'package:flutter_unit/views/home/home_light_drawer.dart'; import 'package:flutter_unit/views/widgets/StatelessWidget/FloatingActionButton.dart'; -import 'act_page.dart'; +import 'collect_page.dart'; +import 'setting/home_drawer.dart'; import 'home_page.dart'; import 'love_page.dart'; import 'me_page.dart'; @@ -38,67 +46,92 @@ class _UnitNavigationState extends State { Widget build(BuildContext context) { return BlocBuilder( builder: (_, state) => Scaffold( - floatingActionButtonLocation: - FloatingActionButtonLocation.centerDocked, - floatingActionButton: FloatingActionButton( - backgroundColor: state.color, -// shape: StarBorder(), - child: Icon(Icons.search), - onPressed: () { - Navigator.of(context).pushNamed(Router.search); - }, - ), - body: PageView( - //使用PageView实现五个页面的切换 - controller: _controller, - children: [ - HomePage(), - ActPage(), -// LovePage(), -// NotePage(), -// MePage(), - ], - ), - bottomNavigationBar: _buildBottomNavigationBar(state.color), + drawer: HomeDrawer(), //左滑页 + endDrawer: HomeDrawer(), //右滑页 + floatingActionButtonLocation: + FloatingActionButtonLocation.centerDocked, + floatingActionButton: FloatingActionButton( + backgroundColor: state.color, + child: Icon(Icons.search), + onPressed: () { + Navigator.of(context).pushNamed(Router.search); + }, + ), + body: PageView( + physics: NeverScrollableScrollPhysics(), + //使用PageView实现页面的切换 + controller: _controller, + children: [ + HomePage(), + CollectPage(), + ], + ), + bottomNavigationBar: + UnitBottomBar( + color: state.color, + itemData: Cons.ICONS_MAP, onItemClick: _onTapNav) + +// _buildBottomNavigationBar(state.color), )); } -// Color antiColor(Color color) { -// print(color.alpha); -// return Color.fromARGB( -// color.alpha, 255 - color.red, 255 - color.green, 255 - color.blue) -// .withAlpha(99); -// } + _onTapNav(int index) { + _controller.animateToPage(index, duration: Duration(milliseconds: 200), curve: Curves.linear); + if (index == 1) { + BlocProvider.of(context).add(EventSetCollectData()); + } + } +} - Widget _buildBottomNavigationBar(Color color) { +class UnitBottomBar extends StatefulWidget { + final Color color; + final Map itemData; + final Function(int) onItemClick; + + UnitBottomBar( + {this.color = Colors.blue, + @required this.itemData, + @required this.onItemClick}); + + @override + _UnitBottomBarState createState() => _UnitBottomBarState(); +} + +class _UnitBottomBarState extends State { + int _position = 0; + + @override + Widget build(BuildContext context) { return BottomAppBar( elevation: 0, shape: CircularNotchedRectangle(), notchMargin: 5, - color: color, + color: widget.color, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: Cons.ICONS_MAP.keys - .map((e) => _buildChild(info.indexOf(e), color)) + children: widget.itemData.keys + .map((e) => _buildChild(info.indexOf(e), widget.color)) .toList(), )); } - List get info => Cons.ICONS_MAP.keys.toList(); - - var activeColor = Colors.blue.withAlpha(240); + List get info => widget.itemData.keys.toList(); Widget _buildChild(int i, Color color) { var active = i == _position; bool left = i == 0; return GestureDetector( - onTap: () { - setState(() { - _position = i; - _controller.animateToPage(_position, - duration: Duration(milliseconds: 200), curve: Curves.linear); - }); - }, + onTap: () => setState(() { + _position = i; + if (widget.onItemClick != null) { + widget.onItemClick(_position); + } +// _controller.animateToPage(_position, +// duration: Duration(milliseconds: 200), curve: Curves.linear); +// if(_position==1){ +// BlocProvider.of(context).add(EventSetCollectData()); +// } + }), child: Material( elevation: 2, shape: RoundedRectangleBorder( @@ -118,7 +151,7 @@ class _UnitNavigationState extends State { height: 45, width: 100, child: Icon( - Cons.ICONS_MAP[info[i]], + widget.itemData[info[i]], color: active ? color : Colors.white, size: active ? 28 : 24, )), diff --git a/lib/views/unit_splash.dart b/lib/views/unit_splash.dart index ab555e5..a5fca74 100644 --- a/lib/views/unit_splash.dart +++ b/lib/views/unit_splash.dart @@ -5,9 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_unit/app/router.dart'; -import 'package:flutter_unit/components/colorful_text.dart'; -import 'package:flutter_unit/components/flutter_text.dart'; - +//import 'package:flutter_unit/components/colorful_text.dart'; /// create by 张风捷特烈 on 2020-03-07 /// contact me by email 1981462002@qq.com /// 说明: @@ -31,8 +29,8 @@ class _UnitSplashState extends State with TickerProviderStateMixin { Animation _bouncAnim; bool _animEnd = false; - final Widget flutter = ColorfulText("Flutter"); - final Widget unit = ColorfulText(" Unit"); +// final Widget flutter = ColorfulText("Flutter"); +// final Widget unit = ColorfulText(" Unit"); @override void initState() { @@ -121,22 +119,44 @@ class _UnitSplashState extends State with TickerProviderStateMixin { child: AnimatedOpacity( duration: Duration(milliseconds: 300), opacity: _animEnd ? 1.0 : 0.0, - child: flutter), + child: Text('Flutter',style: TextStyle( + fontSize: 45, + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + shadows: [ + Shadow( + //阴影 + color: Colors.grey, + offset: Offset(1.0, 1.0), blurRadius: 1.0, + ) + ], + ),)), ), Positioned( - top: winH / 1.4 * (0.4 * _bouncAnim.value + 0.6), + top: winH / 1.4 * (0.2 * _bouncAnim.value + 0.8), left: winW * 0.55, child: AnimatedOpacity( duration: Duration(milliseconds: 300), opacity: _animEnd ? 1.0 : 0.0, - child: unit), + child: Text('Unit',style: TextStyle( + fontSize: 45, + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + shadows: [ + Shadow( + //阴影 + color: Colors.grey, + offset: Offset(1.0, 1.0), blurRadius: 1.0, + ) + ], + ),)), ), Positioned( bottom: 30, right: 30, child: AnimatedOpacity( duration: Duration(milliseconds: 300), - opacity: _animEnd ? 1.0 : 0.0, + opacity: _animEnd ? 1.0: 0.0, child: Text("Power By 张风捷特烈", style: TextStyle( color: Colors.grey, diff --git a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Column.dart b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Column.dart index 920a7ed..bd3b370 100644 --- a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Column.dart +++ b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Column.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_unit/components/multi_shower.dart'; // { // "widgetId": 95, diff --git a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Flex.dart b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Flex.dart index 0764dad..e42962e 100644 --- a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Flex.dart +++ b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Flex.dart @@ -1,9 +1,276 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_unit/components/multi_shower.dart'; + + + // { // "widgetId": 94, -// "name": 'Flex基本使用', +// "name": 'Flex的排布方向基本使用', +// "priority": 1, +// "subtitle": +// "【children】 : 组件列表 【List】\n" +// "【direction】 : 方向 【Axis】", +// } +class DirectionFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + children: Axis.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); + } + + _buildItem(mode) => Flex( + direction: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +} + +// { +// "widgetId": 94, +// "name": 'Flex主轴对齐方式', +// "priority": 2, +// "subtitle": +// "【mainAxisAlignment】 : 主轴对齐 【MainAxisAlignment】", +// } +class MainAxisAlignmentFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: MainAxisAlignment.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); + } + + _buildItem(mode) => Flex( + direction: Axis.horizontal, + mainAxisAlignment: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +} + + +// { +// "widgetId": 94, +// "name": 'Flex交叉轴对齐方式', +// "priority": 3, +// "subtitle": +// "【crossAxisAlignment】 : 交叉轴对齐 【CrossAxisAlignment】", +// } +class CrossAxisAlignmentFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: CrossAxisAlignment.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); + } + + _buildItem(mode) => Flex( + direction: Axis.horizontal, + crossAxisAlignment: mode, + textBaseline: TextBaseline.alphabetic, + children: [ + blueBox, redBox, greenBox + ], + ); +} +// { +// "widgetId": 94, +// "name": 'Flex垂直方向顺序', +// "priority": 4, +// "subtitle": +// "【verticalDirection】 : 垂直方向顺序 【VerticalDirection】", +// } +class VerticalDirectionFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: VerticalDirection.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); + } + + _buildItem(mode) => Flex( + direction: Axis.vertical, + verticalDirection: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +} +// { +// "widgetId": 94, +// "name": 'Flex水平方向顺序', +// "priority": 5, +// "subtitle": +// "【textDirection】 : 水平方向顺序 【TextDirection】", +// } +class TextDirectionFlex extends StatelessWidget { + + final redBox= Container( + color: Colors.red, + height: 30, + width: 40, + ); + + final blueBox= Container( + color: Colors.blue, + height: 20, + width: 30, + ); + + final greenBox= Container( + color: Colors.green, + height: 20, + width: 20, + ); + + @override + Widget build(BuildContext context) { + return Wrap( + runSpacing: 5, + children: TextDirection.values + .map((mode) => Column(children: [ + Container( + margin: EdgeInsets.all(5), + width: 160, + height: 80, + color: Colors.grey.withAlpha(33), + child: _buildItem(mode)), + Text(mode.toString().split('.')[1]) + ])) + .toList()); + } + + _buildItem(mode) => Flex( + direction: Axis.horizontal, + textDirection: mode, + children: [ + blueBox, redBox, greenBox + ], + ); +} + + +// { +// "widgetId": 94, +// "name": 'Flex主轴对齐方式', // "priority": 1, // "subtitle": // "【children】 : 组件列表 【List】\n" @@ -14,12 +281,12 @@ import 'package:flutter_unit/components/multi_shower.dart'; // "【verticalDirection】 : 竖直方向 【VerticalDirection】\n" // "【mainAxisSize】 : 主轴尺寸 【MainAxisSize】", // } -class CustomFlex extends StatefulWidget { +class PlayFlex extends StatefulWidget { @override - _CustomFlexState createState() => _CustomFlexState(); + _PlayFlexState createState() => _PlayFlexState(); } -class _CustomFlexState extends State { +class _PlayFlexState extends State { final redBox = Container( color: Colors.red, height: 50, diff --git a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Row.dart b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Row.dart index f7ed308..ddcac5d 100644 --- a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Row.dart +++ b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Row.dart @@ -1,7 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_unit/components/multi_shower.dart'; - // { // "widgetId": 95, // "name": 'Row基本使用', diff --git a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Wrap.dart b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Wrap.dart index 92045b9..92293f8 100644 --- a/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Wrap.dart +++ b/lib/views/widgets/RenderObjectWidget/MultiChildRenderObjectWidget/Wrap.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_unit/components/multi_shower.dart'; // { // "widgetId": 98, // "name": 'Wrap的基础用法', @@ -24,7 +23,7 @@ class DirectionWrap extends StatelessWidget { child: _buildItem(mode)), Text(mode.toString().split('.')[1]) ])) - .toList());; + .toList()); } final yellowBox = Container( color: Colors.yellow, diff --git a/lib/views/widgets/StatelessWidget/CupertinoTheme.dart b/lib/views/widgets/StatelessWidget/CupertinoTheme.dart index 0fda822..7da2774 100644 --- a/lib/views/widgets/StatelessWidget/CupertinoTheme.dart +++ b/lib/views/widgets/StatelessWidget/CupertinoTheme.dart @@ -59,22 +59,44 @@ class TextCupertinoTheme extends StatelessWidget { } // { -// "widgetId": 168, -// "name": 'CupertinoThemeData的toString', +// "widgetId": 169, +// "name": 'CupertinoThemeData的使用', // "priority": 2, // "subtitle": -// "", +// "和Theme一样可以通过指定的属性,让它们在后代中共享,不过属性较少。注意如果需要使用主题,不能在当前的context中获取。", // } + class CustomCupertinoTheme extends StatelessWidget { @override Widget build(BuildContext context) { - var queryData = CupertinoTheme.of(context); - return Container( - child: Text(queryData.toString(), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.blue, - )), - ); + return CupertinoTheme( + data: CupertinoThemeData( + primaryColor: Colors.blue, + primaryContrastingColor: Colors.green + ), + child: _ChildUseTheme()); + } +} + +class _ChildUseTheme extends StatelessWidget { + const _ChildUseTheme({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Container( + width: 50, + height: 50, + color: CupertinoTheme.of(context).primaryContrastingColor, + ), + Container( + width: 150, + child: Slider(value: 0.8, onChanged: (v) => {})), + Container( width: 150,child: Divider(color:CupertinoTheme.of(context).primaryContrastingColor,thickness: 1,)) + ]); } } diff --git a/lib/views/widgets/StatelessWidget/Icon.dart b/lib/views/widgets/StatelessWidget/Icon.dart index ca73702..2d422eb 100644 --- a/lib/views/widgets/StatelessWidget/Icon.dart +++ b/lib/views/widgets/StatelessWidget/Icon.dart @@ -31,7 +31,7 @@ class MyIcon extends StatelessWidget { children: [ TolyIcon.icon_search, TolyIcon.icon_star, - TolyIcon.icon_widgit, + TolyIcon.icon_layout, TolyIcon.icon_star_ok ] .map((e) => Icon( diff --git a/lib/views/widgets/StatelessWidget/Text.dart b/lib/views/widgets/StatelessWidget/Text.dart index 58b98ae..c2ae0f1 100644 --- a/lib/views/widgets/StatelessWidget/Text.dart +++ b/lib/views/widgets/StatelessWidget/Text.dart @@ -5,7 +5,7 @@ class CustomText extends StatelessWidget { @override Widget build(BuildContext context) { var style = TextStyle( - color: Colors.red, + color: Colors.blue, fontSize: 20, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, @@ -33,7 +33,7 @@ class DecorationText extends StatelessWidget { decorationStyle: TextDecorationStyle.wavy, decorationColor: Colors.blue, fontStyle: FontStyle.italic, - fontFamily: "Menlo", + fontFamily: "DancingScript", letterSpacing: 10), ); } diff --git a/lib/views/widgets/StatelessWidget/Theme.dart b/lib/views/widgets/StatelessWidget/Theme.dart index 56fc8f3..66e1763 100644 --- a/lib/views/widgets/StatelessWidget/Theme.dart +++ b/lib/views/widgets/StatelessWidget/Theme.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; // "name": '文字样式-ThemeData#TextTheme', // "priority": 1, // "subtitle": -// "", +// "子组件可以通过ThemeData.of获取主题的数据进行使用。", // } class TextThemeDemo extends StatelessWidget { @override @@ -64,21 +64,40 @@ class TextThemeDemo extends StatelessWidget { // { // "widgetId": 168, -// "name": 'ThemeData的toString', +// "name": 'Theme的用法', // "priority": 2, // "subtitle": -// "", +// "使用Theme,可以指定非常多的属性作为主题,这些属性将应用于所有的后代组件,如指定字体、滑块、卡片、文字、分割线、按钮等属性。", // } class CustomTheme extends StatelessWidget { @override Widget build(BuildContext context) { - var queryData = Theme.of(context); - return Container( - child: Text(queryData.toString(), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.blue, - )), - ); + return Theme( + data: ThemeData( + cardTheme: CardTheme(color: Colors.red, elevation: 4), + dividerTheme: DividerThemeData( + color: Colors.blue, + thickness: 2 + ), + sliderTheme: SliderThemeData( + thumbColor: Colors.red, + activeTrackColor: Colors.green, + inactiveTrackColor: Colors.grey, + )), + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Card( + child: Container( + width: 50, + height: 50, + color: Colors.transparent, + ), + ), + Container( + width: 150, + child: Slider(value: 0.8, onChanged: (v) => {})), + Container( width: 150,child: Divider()) + ])); } } diff --git a/lib/views/widgets/widgets_map.dart b/lib/views/widgets/widgets_map.dart index 8cf6b6e..7ec127b 100644 --- a/lib/views/widgets/widgets_map.dart +++ b/lib/views/widgets/widgets_map.dart @@ -454,7 +454,11 @@ class WidgetsMap { ]; case "Flex": return [ - CustomFlex(), + DirectionFlex(), + MainAxisAlignmentFlex(), + CrossAxisAlignmentFlex(), + VerticalDirectionFlex(), + TextDirectionFlex(), ]; case "Row": return [ diff --git a/picture/page1.png b/picture/page1.png new file mode 100644 index 0000000..0932baf Binary files /dev/null and b/picture/page1.png differ diff --git a/picture/page10.png b/picture/page10.png new file mode 100644 index 0000000..505ba56 Binary files /dev/null and b/picture/page10.png differ diff --git a/picture/page2.png b/picture/page2.png new file mode 100644 index 0000000..fbf13d9 Binary files /dev/null and b/picture/page2.png differ diff --git a/picture/page3.png b/picture/page3.png new file mode 100644 index 0000000..92b0eb7 Binary files /dev/null and b/picture/page3.png differ diff --git a/picture/page4.png b/picture/page4.png new file mode 100644 index 0000000..f95c183 Binary files /dev/null and b/picture/page4.png differ diff --git a/picture/page5.png b/picture/page5.png new file mode 100644 index 0000000..a64846d Binary files /dev/null and b/picture/page5.png differ diff --git a/picture/page6.png b/picture/page6.png new file mode 100644 index 0000000..601c244 Binary files /dev/null and b/picture/page6.png differ diff --git a/picture/page7.png b/picture/page7.png new file mode 100644 index 0000000..80ff63d Binary files /dev/null and b/picture/page7.png differ diff --git a/picture/page8.png b/picture/page8.png new file mode 100644 index 0000000..8c4b867 Binary files /dev/null and b/picture/page8.png differ diff --git a/picture/page9.png b/picture/page9.png new file mode 100644 index 0000000..85b515f Binary files /dev/null and b/picture/page9.png differ diff --git a/pubspec.lock b/pubspec.lock index b451e2b..cc5d886 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -109,6 +109,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" image: dependency: transitive description: @@ -179,6 +184,34 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.23.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.5.6+3" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.1+6" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.2+4" sky_engine: dependency: transitive description: flutter @@ -277,4 +310,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.1 <2.0.0" + flutter: ">=1.12.13+hotfix.4 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index f122628..ddfdce5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,6 +27,7 @@ dependencies: sqflite: ^1.2.1 #数据库 toggle_rotate: ^0.0.5 flutter_star: ^0.1.2 # 星星组件 + shared_preferences: ^0.5.6+3 # xml 固化 flutter_circle_color_picker: ^0.1.1 dev_dependencies: flutter_test: @@ -47,7 +48,6 @@ flutter: - assets/images/ - assets/images/head_icon/ - assets/images/widgets/ - - assets/data/data.json - assets/data/widget.json # To add assets to your application, add an assets section, like this: # assets: @@ -66,12 +66,21 @@ flutter: # list giving the asset and other descriptors for the font. For # example: fonts: # 配置字体,可配置多个,支持ttf和otf,ttc等字体资源 - - family: 阿里惠普体 #字体名 + - family: IndieFlower #字体名 fonts: - - asset: assets/fonts/Alibaba-PuHuiTi-Medium.otf - - family: Menlo #字体名 + - asset: assets/fonts/IndieFlower-Regular.ttf + - family: BalooBhai2 #字体名 fonts: - - asset: assets/fonts/Menlo.ttc + - asset: assets/fonts/BalooBhai2-Regular.ttf + - family: Inconsolata #字体名 + fonts: + - asset: assets/fonts/Inconsolata-Regular.ttf + - family: Neucha #字体名 + fonts: + - asset: assets/fonts/Neucha-Regular.ttf + - family: ComicNeue #字体名 + fonts: + - asset: assets/fonts/ComicNeue-Regular.ttf - family: TolyIcon fonts: - asset: assets/iconfont/iconfont.ttf \ No newline at end of file