diff --git a/docs/widget/regular/aspectratio/index.md b/docs/widget/regular/aspectratio/index.md new file mode 100644 index 0000000..86b052e --- /dev/null +++ b/docs/widget/regular/aspectratio/index.md @@ -0,0 +1,19 @@ +## **AspectRatio** + +> +将子控件调整为特定宽高比的控件 +* AspectRatio 首先会尝试布局约束的最大宽度,widget的高度是通过给定的宽度和宽高比率来决定的 +* 对于需要缩放调整位置的,一般是对图片的处理 + +### 构造方法 +``` dart +AspectRatio({ + Key key, + @required this.aspectRatio, + Widget child +}) +``` + +### 属性介绍 +* aspectRatio: 宽高比,如1.5,宽度是高度的1.5倍 +* child: AspectRatio中的内容widget \ No newline at end of file diff --git a/docs/widget/regular/constrainedbox/index.md b/docs/widget/regular/constrainedbox/index.md new file mode 100644 index 0000000..bc299ce --- /dev/null +++ b/docs/widget/regular/constrainedbox/index.md @@ -0,0 +1,20 @@ +## **ConstrainedBox** + +> +一个基础布局控件,添加额外的限制条件(constraints)到child上 + +### 构造方法 +``` dart +ConstrainedBox({ + Key key, + @required this.constraints, + Widget child +}) +``` + +### 属性介绍 +* constraints: 添加到child上的额外限制条件,其类型为BoxConstraints,限制各种最大最小宽高 +* child: ConstrainedBox中的内容Widget + +### 其他用法 +* constraints值为BoxConstraints.expand时,提供width或者height,那么限制(Constraints)将严格使用给出的width或者height值 \ No newline at end of file diff --git a/docs/widget/regular/flow/index.md b/docs/widget/regular/flow/index.md new file mode 100644 index 0000000..60f4f40 --- /dev/null +++ b/docs/widget/regular/flow/index.md @@ -0,0 +1,23 @@ +## **Flow** + +> +实现优化流式布局以使用流布局的控件 +* 实现较为复杂,一般可通过Wrap来替换实现 + +### 构造方法 +``` dart +Flow({ + Key key, + @required this.delegate, + List children = const [], +}) +``` + +### 属性介绍 +* delegeate: 影响布局的FlowDelegate,包含方法如下: + * paintChildren: child的绘制控制代码,可以调整尺寸位置 + * shouldPepaint:是否需要重绘 + * shouldRelayout:是否需要重新布局 + * getConstraintsForChild:设置每个child的约束条件,会覆盖已有 + * getSize: 设置Flow的尺寸 +* children: Flow中的内容widget \ No newline at end of file diff --git a/docs/widget/regular/stack/index.md b/docs/widget/regular/stack/index.md new file mode 100644 index 0000000..c94fe73 --- /dev/null +++ b/docs/widget/regular/stack/index.md @@ -0,0 +1,31 @@ +## **Stack** + +> +该Widget将子控件相对于其边框进行定位 +* Stack的布局行为,根据child是positioned节点还是non-positioned节点来区分 + * 对于positioned的子节点,它们的位置会根据所设置的top、bottom、right以及left属性来确定,这几个值都是相对于Stack的左上角; + * 对于non-positioned的子节点,它们会根据Stack的aligment来设置位置。 +* 对应child的顺序,第一个child会被绘制在最低端 + +### 构造方法 +``` dart +Stack({ + Key key, + this.alignment = AlignmentDirectional.topStart, + this.textDirection, + this.fit = StackFit.loose, + this.overflow = Overflow.clip, + List children = const [], +}) +``` + +### 属性介绍 +* alignment: 对齐方式,默认是topLeft +* textDirection:文本方向,不常用 +* fit: 默认loose + * loose:子节点尺寸可以从min到max + * expand:子节点尽可能占用空间 + * passthrough: 不改变子节点约束 +* overflow:超过部分是否裁切,Overflow.clip/visible +* children: Stack中的内容Widget + diff --git a/docs/widget/regular/table/index.md b/docs/widget/regular/table/index.md new file mode 100644 index 0000000..c2d0399 --- /dev/null +++ b/docs/widget/regular/table/index.md @@ -0,0 +1,35 @@ +## **Table** + +> +该控件为其子控件进行table布局的Widget + +### 构造方法 +``` dart +Table({ + Key key, + this.children = const [], + this.columnWidths, + this.defaultColumnWidth = const FlexColumnWidth(1.0), + this.textDirection, + this.border, + this.defaultVerticalAlignment = TableCellVerticalAlignment.top, + this.textBaseline, +}) +``` + +### 属性介绍 +> +该Widget适用于多行多列,若只有一行或者一列,选择Row或Column会更合适一些 + +* columnWidths:设置每一列的宽度 +* defaultColumnWidth:默认的每一列宽度值,默认情况下均分,通过FixedColumnWidth设置 +* textDirection:文字显示方向 +* border:表格边框 +* defaultVerticalAlignment:每一个cell的垂直方向的对齐方式, 包含5种: + * top:放置在的顶部; + * middle:垂直居中; + * bottom:放置在底部; + * baseline:文本baseline对齐; + * fill:充满整个cell。 +* textBaseline:defaultVerticalAlignment为baseline的时候,会用到这个属性。 +* children: Table的中的内容widget \ No newline at end of file diff --git a/docs/widget/regular/wrap/index.md b/docs/widget/regular/wrap/index.md new file mode 100644 index 0000000..1349cf4 --- /dev/null +++ b/docs/widget/regular/wrap/index.md @@ -0,0 +1,32 @@ +## **Wrap** + +> +该控件以多个水平或垂直方向显示其子控件 +* 单行的Wrap和Row表现几乎一致,单列的Wrap和Column表现几乎一致,但是Row同Column系单行单列的,Wrap中行或列空间不足时,会自动换行 + +### 构造方法 +``` dart +Wrap({ + Key key, + this.direction = Axis.horizontal, + this.alignment = WrapAlignment.start, + this.spacing = 0.0, + this.runAlignment = WrapAlignment.start, + this.runSpacing = 0.0, + this.crossAxisAlignment = WrapCrossAlignment.start, + this.textDirection, + this.verticalDirection = VerticalDirection.down, + List children = const [], +}) +``` + +### 属性介绍 +* direction:主轴的方向,默认为水平,值:Axis.horizontal/vertical +* alignment:主轴方向上的对齐方式,默认为start, 值: WrapAlignment.start/center/end/spaceAround/spaceBetween/spaceEvenly +* spacing:主轴方向上的间距。 +* runAlignment:run的对齐方式, 值: WrapAlignment.start/center/end/spaceAround/spaceBetween/spaceEvenly +* runSpacing:run的间距。 +* crossAxisAlignment:交叉轴(crossAxis)方向上的对齐方式,值: WrapCrossAlignment.start/center/end +* textDirection:文本方向, 值:TextDirection.ltr/rtl +* verticalDirection:定义了children摆放顺序,默认是down,值: VerticalDirection.down/up +* children: Table的中的内容widget diff --git a/git.md b/git.md new file mode 100644 index 0000000..d169d05 --- /dev/null +++ b/git.md @@ -0,0 +1,9 @@ +# git使用规范 +## 提交规范 ++ feat:新功能(feature) ++ fix:修补bug ++ docs:文档(documentation) ++ style: 格式(不影响代码运行的变动) ++ refactor:重构(即不是新增功能,也不是修改bug的代码变动) ++ test:增加测试 ++ chore:构建过程或辅助工具的变动 \ No newline at end of file diff --git a/lib/components/exampleComp.dart b/lib/components/exampleComp.dart index d128832..91862d0 100644 --- a/lib/components/exampleComp.dart +++ b/lib/components/exampleComp.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:efox_flutter/store/models/main_state_model.dart' show MainStateModel; +import 'package:efox_flutter/store/models/main_state_model.dart' + show MainStateModel; import 'package:efox_flutter/store/store.dart' show Store; +import 'package:efox_flutter/config/theme.dart' show AppTheme; class Index extends StatelessWidget { final Widget child; - Index({Key key, this.child}):super(key: key); + Index({Key key, this.child}) : super(key: key); @override Widget build(BuildContext context) { @@ -15,14 +17,11 @@ class Index extends StatelessWidget { height: 420.0, margin: EdgeInsets.fromLTRB(50, 40, 50, 40), decoration: BoxDecoration( - border: Border.all( - color: Color(model.theme.mainColor), - width: 1.0 - ), + border: Border.all(color: Color(AppTheme.mainColor), width: 1.0), ), child: this.child, ); }, ); } -} \ No newline at end of file +} diff --git a/lib/components/widgetComp.dart b/lib/components/widgetComp.dart index 413cbf0..596e20c 100644 --- a/lib/components/widgetComp.dart +++ b/lib/components/widgetComp.dart @@ -8,6 +8,7 @@ import 'package:efox_flutter/components/exampleComp.dart' as ExampleComp; import 'package:efox_flutter/utils/file.dart' as FileUtils; import 'package:efox_flutter/utils/loadAsset.dart' as LoadAssetUtils; import 'package:efox_flutter/router/index.dart' show FluroRouter; +import 'package:efox_flutter/config/theme.dart' show AppTheme; class Index extends StatefulWidget { final List demoChild; @@ -149,7 +150,7 @@ class IndexState extends State { child: Row(children: [ Icon( Icons.home, - color: Color(model.theme.greyColor), + color: Color(AppTheme.greyColor), ), Text(" "), Text('Flutter-UI'), @@ -160,7 +161,7 @@ class IndexState extends State { child: Row(children: [ Icon( Icons.code, - color: Color(model.theme.greyColor), + color: Color(AppTheme.greyColor), ), Text(" "), Text(this.title), @@ -205,8 +206,7 @@ class IndexState extends State { child: Text( AppTranslations.of(context).t('loading'), style: TextStyle( - color: Color(this.model.theme.secondColor), - fontSize: 20.0), + color: Color(AppTheme.secondColor), fontSize: 20.0), ), ) ], diff --git a/lib/config/theme.dart b/lib/config/theme.dart new file mode 100644 index 0000000..4746a6c --- /dev/null +++ b/lib/config/theme.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +class AppTheme { + static int mainColor = 0xFFD32F2F; + static int secondColor = 0xFFFFFFFF; + static int thirdColor = 0xFFFAFAFA; + static int greyColor = 0x8A000000; + static int blackColor = 0xFF000000; + static ThemeData themData = ThemeData( + textTheme: TextTheme( + body1: TextStyle( + // color: Colors.black, + // fontWeight: FontWeight.bold, + ), + ), + platform: TargetPlatform.iOS, + iconTheme: IconThemeData( + size: 32, + color: Color(thirdColor), + opacity: 0.85, + ), + // primaryIconTheme 导航栏按钮颜色 + primaryIconTheme: IconThemeData( + color: Color(secondColor), + ), + accentColor: Colors.grey, // 选中颜色 + primaryColor: Color(mainColor), // appbar背景 + scaffoldBackgroundColor: Color(thirdColor), // 整体的scaffold背景颜色 + ); +} diff --git a/lib/main.dart b/lib/main.dart index e76b9a6..738b618 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,9 @@ import 'package:efox_flutter/lang/app_translations_delegate.dart'; import 'package:efox_flutter/store/store.dart' show model, Store; //路由 import 'package:efox_flutter/router/index.dart'; +//主题 +import 'package:efox_flutter/config/theme.dart' show AppTheme; + void main() => runApp(MainApp()); class MainApp extends StatefulWidget { @@ -56,27 +59,7 @@ class MainAppState extends State { const Locale('zh'), ], title: 'Flutter Demo', - theme: ThemeData( - textTheme: TextTheme( - body1: TextStyle( - // color: Colors.black, - // fontWeight: FontWeight.bold, - ), - ), - platform: TargetPlatform.iOS, - iconTheme: IconThemeData( - size: 32, - color: Color(model.theme.thirdColor), - opacity: 0.85, - ), - // primaryIconTheme 导航栏按钮颜色 - primaryIconTheme: IconThemeData( - color: Color(model.theme.secondColor), - ), - accentColor: Colors.grey, // 选中颜色 - primaryColor: Color(model.theme.mainColor), // appbar背景 - scaffoldBackgroundColor: Color(model.theme.thirdColor), // 整体的scaffold背景颜色 - ), + theme: AppTheme.themData, onGenerateRoute: FluroRouter.router.generator, ), ); diff --git a/lib/page/component/index.dart b/lib/page/component/index.dart index d51a8bd..7bbcc0b 100644 --- a/lib/page/component/index.dart +++ b/lib/page/component/index.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:efox_flutter/router/index.dart'; import 'package:efox_flutter/store/models/main_state_model.dart'; import 'package:efox_flutter/widget/index.dart' as WidgetRoot; +import 'package:efox_flutter/config/theme.dart' show AppTheme; class Index extends StatefulWidget { final MainStateModel model; @@ -43,7 +44,7 @@ class _IndexState extends State { fontFamily: 'MaterialIcons', matchTextDirection: true, ), - // color: Color(model.theme.mainColor), + // color: Color(AppTheme.mainColor), ), backgroundColor: Colors.white, children: [ @@ -74,7 +75,7 @@ class _IndexState extends State { fontFamily: 'MaterialIcons', matchTextDirection: true, ), - color: Color(model.theme.mainColor), + color: Color(AppTheme.mainColor), ), onPressed: () { FluroRouter.router.navigateTo( diff --git a/lib/page/home.dart b/lib/page/home.dart index cffa21c..7f545a9 100644 --- a/lib/page/home.dart +++ b/lib/page/home.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; import 'package:efox_flutter/lang/application.dart'; import 'package:efox_flutter/lang/app_translations.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; // import 'package:efox_flutter/store/store.dart' show Store, MainStateModel; import 'package:efox_flutter/components/header.dart' as Header; import 'component/index.dart' as TabIndex; import 'mine/index.dart' as MyIndex; +import 'package:efox_flutter/config/theme.dart' show AppTheme; class Index extends StatefulWidget { @override @@ -14,18 +16,29 @@ class Index extends StatefulWidget { } class _IndexState extends State with SingleTickerProviderStateMixin { + int _currentIndex = 0; + PageController _pageController; + @override void initState() { super.initState(); + _pageController = PageController(); + } + + @override + void dispose() { + _pageController.dispose(); + super.dispose(); } + //::TODO 保留到下个版本 考虑去掉 Widget menu(MainStateModel model) { return Container( decoration: BoxDecoration( border: Border( top: BorderSide( width: .1, - color: Color(model.theme.greyColor), + color: Color(AppTheme.greyColor), ), ), ), @@ -34,14 +47,14 @@ class _IndexState extends State with SingleTickerProviderStateMixin { border: Border( bottom: BorderSide( width: .2, - color: Color(model.theme.mainColor), + color: Color(AppTheme.mainColor), ), ), ), - labelColor: Color(model.theme.mainColor), - unselectedLabelColor: Color(model.theme.greyColor), + labelColor: Color(AppTheme.mainColor), + unselectedLabelColor: Color(AppTheme.greyColor), indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Color(model.theme.secondColor), + indicatorColor: Color(AppTheme.secondColor), labelStyle: TextStyle( color: Colors.green, fontWeight: FontWeight.w700, @@ -67,12 +80,30 @@ class _IndexState extends State with SingleTickerProviderStateMixin { ); } + Widget _bottomNavigationBar(model) { + AppTranslations lang = AppTranslations.of(context); + return BottomNavigationBar( + items: [ + BottomNavigationBarItem( + title: Text(lang.t('title_component')), + icon: Icon(Icons.dashboard)), + BottomNavigationBarItem( + title: Text(lang.t('title_my')), icon: Icon(Icons.person_outline)), + ], + type: BottomNavigationBarType.fixed, + currentIndex: _currentIndex, + onTap: (int index) { + _pageController.jumpToPage(index); + }, + ); + } + List appBarActions(model) { return [ PopupMenuButton( icon: Icon( Icons.more_vert, - // color: Color(model.theme.textColor), + // color: Color(AppTheme.textColor), ), onSelected: (local) { Application().onLocaleChanged(Locale(local)); @@ -102,11 +133,12 @@ class _IndexState extends State with SingleTickerProviderStateMixin { @override Widget build(BuildContext context) { + ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context); // 实例化语言包 AppTranslations lang = AppTranslations.of(context); return Store.connect( builder: (context, child, model) { - return DefaultTabController( + /* return DefaultTabController( initialIndex: 0, length: 2, child: Scaffold( @@ -122,6 +154,26 @@ class _IndexState extends State with SingleTickerProviderStateMixin { ], ), ), + ); */ + return Scaffold( + appBar: AppBar( + title: Header.Index(lang.t('title')), + actions: appBarActions(model), + ), + bottomNavigationBar: _bottomNavigationBar(model), + body: PageView( + controller: _pageController, + physics: NeverScrollableScrollPhysics(), + onPageChanged: (int index) { + setState(() { + _currentIndex = index; + }); + }, + children: [ + TabIndex.Index(model: model), + MyIndex.Index(model: model), + ], + ), ); }, ); diff --git a/lib/widget/regular/aspectratio/demo.dart b/lib/widget/regular/aspectratio/demo.dart new file mode 100644 index 0000000..7f21190 --- /dev/null +++ b/lib/widget/regular/aspectratio/demo.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +class Index extends StatefulWidget { + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + var aspectRatio = 1.5; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('AspectRatio'),), + body: ListView( + children: [ + Container( + // margin: const EdgeInsets.only(top: 10.0), + width: double.infinity, + child: AspectRatio( + aspectRatio: aspectRatio, + child: Image.network( + 'http://pic1.win4000.com/wallpaper/2019-01-31/5c52bf7fdc959_270_185.jpg', + fit: BoxFit.cover, + ), + ) + ), + FlatButton( + child: Text('宽度沾满,aspectRatio: $aspectRatio', style: TextStyle(fontSize: 16.0),), + onPressed: (){ + setState(() { + aspectRatio == 1.5 ? aspectRatio = 2.0 : aspectRatio = 1.5; + }); + }, + ) + ], + ) + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/aspectratio/index.dart b/lib/widget/regular/aspectratio/index.dart new file mode 100644 index 0000000..82dee17 --- /dev/null +++ b/lib/widget/regular/aspectratio/index.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; + +class Index extends StatefulWidget { + static String title = 'AspectRatio'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/AspectRatio-class.html'; + static String mdUrl = 'docs/widget/regular/aspectratio/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index() + ], + ); + } +} diff --git a/lib/widget/regular/constrainedbox/demo.dart b/lib/widget/regular/constrainedbox/demo.dart new file mode 100644 index 0000000..ff1bac3 --- /dev/null +++ b/lib/widget/regular/constrainedbox/demo.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; + +class Index extends StatefulWidget { + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + var maxWidth = 200.0; + var maxHeight = 200.0; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('ConstrainedBox'),), + body: ListView( + children: [ + SizedBox( + child: Text('修改maxWidth maxHeight 值'), + ), + Row( + children: [ + FlatButton( + child: Text('maxWidth: $maxWidth', style: TextStyle(fontSize: 14.0),), + onPressed: (){ + setState(() { + maxWidth == 200.0 ? maxWidth = 150.0 : maxWidth = 200.0; + }); + }, + ), + FlatButton( + child: Text('maxHeight: $maxHeight', style: TextStyle(fontSize: 14.0),), + onPressed: (){ + setState(() { + maxHeight == 200.0 ? maxHeight = 150.0 : maxHeight = 200.0; + }); + }, + ) + ], + ), + Center( + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: 100.0, + minHeight: 100.0, + maxWidth: maxWidth, + maxHeight: maxHeight + ), + child: Container( + margin: EdgeInsets.all(10.0), + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage('http://sucimg.itc.cn/avatarimg/55d21fdc4b8d4838bef0da94ada78cab_1501139484387') + ), + color: Theme.of(context).primaryColor, + ), + ), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/constrainedbox/demo_expand.dart b/lib/widget/regular/constrainedbox/demo_expand.dart new file mode 100644 index 0000000..f916529 --- /dev/null +++ b/lib/widget/regular/constrainedbox/demo_expand.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +class Index extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Expand'),), + body: Center( + child: ConstrainedBox( + constraints: BoxConstraints.expand( + width: 150.0, + height: 150.0 + ), + child: Container( + alignment: Alignment.center, + color: Theme.of(context).primaryColor, + child: Text( + 'Hello World', + style: TextStyle(fontSize: 20.0, color: Colors.white, fontWeight: FontWeight.bold) + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/constrainedbox/index.dart b/lib/widget/regular/constrainedbox/index.dart new file mode 100644 index 0000000..a299358 --- /dev/null +++ b/lib/widget/regular/constrainedbox/index.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; +import 'demo_expand.dart' as DemoExpand; + +class Index extends StatefulWidget { + static String title = 'ConstrainedBox'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/ConstrainedBox-class.html'; + static String mdUrl = 'docs/widget/regular/constrainedbox/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index(), + DemoExpand.Index() + ], + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/fittedbox/index.dart b/lib/widget/regular/fittedbox/index.dart index 61fcacd..7d7679d 100644 --- a/lib/widget/regular/fittedbox/index.dart +++ b/lib/widget/regular/fittedbox/index.dart @@ -4,7 +4,7 @@ import 'demo.dart' as Demo; class Index extends StatefulWidget { static String title = 'FittedBox'; - static String originCodeUrl = ''; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/FittedBox-class.html'; static String mdUrl = 'docs/widget/regular/fittedbox/index.md'; @override _IndexState createState() => _IndexState(); diff --git a/lib/widget/regular/flow/demo.dart b/lib/widget/regular/flow/demo.dart new file mode 100644 index 0000000..40dbe0a --- /dev/null +++ b/lib/widget/regular/flow/demo.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; + +class Index extends StatelessWidget { + List containerValue = [ + Colors.deepOrangeAccent, + Colors.cyanAccent, + Colors.limeAccent, + Colors.deepPurpleAccent, + Colors.indigo, + Colors.lightGreenAccent + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Flow'),), + body: Flow( + delegate: FlowDelegateFunc(margin: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0)), + children: List.generate(6, (index) { + return Container( + width: 46.0, + height: 40.0, + color: containerValue[index], + ); + }), + ), + ); + } +} + +class FlowDelegateFunc extends FlowDelegate { + EdgeInsets margin = EdgeInsets.zero; + + FlowDelegateFunc({this.margin}); + @override + void paintChildren(FlowPaintingContext context) { + var x = margin.left; + var y = margin.top; + for (int i = 0; i < context.childCount; i++) { + var w = context.getChildSize(i).width + x + margin.right; + if (w < context.size.width) { + context.paintChild(i, + transform: new Matrix4.translationValues( + x, y, 0.0)); + x = w + margin.left; + } else { + x = margin.left; + y += context.getChildSize(i).height + margin.top + margin.bottom; + context.paintChild(i, + transform: new Matrix4.translationValues( + x, y, 0.0)); + x += context.getChildSize(i).width + margin.left + margin.right; + } + } + } + + @override + bool shouldRepaint(FlowDelegate oldDelegate) { + return oldDelegate != this; + } +} \ No newline at end of file diff --git a/lib/widget/regular/flow/index.dart b/lib/widget/regular/flow/index.dart new file mode 100644 index 0000000..31d6a37 --- /dev/null +++ b/lib/widget/regular/flow/index.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; + +class Index extends StatefulWidget { + static String title = 'Flow'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/Flow-class.html'; + static String mdUrl = 'docs/widget/regular/flow/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index() + ], + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/index.dart b/lib/widget/regular/index.dart index 43123d6..583bd7e 100644 --- a/lib/widget/regular/index.dart +++ b/lib/widget/regular/index.dart @@ -6,6 +6,12 @@ import 'padding/index.dart' as Padding; import 'align/index.dart' as Align; import 'center/index.dart' as Center; import 'fittedbox/index.dart' as FittedBox; +import 'aspectratio/index.dart' as AspectRatio; +import 'constrainedbox/index.dart' as ConstrainedBox; +import 'wrap/index.dart' as Wrap; +import 'table/index.dart' as Table; +import 'flow/index.dart' as Flow; +import 'stack/index.dart' as Stack; const nameSpaces = '/regular_'; @@ -44,6 +50,36 @@ List widgets = [ widget: FittedBox.Index(), code: 60231, // format_indent_decrease title: FittedBox.Index.title + ), + ItemInfo( + widget: AspectRatio.Index(), + code: 58688, // local_bar + title: AspectRatio.Index.title + ), + ItemInfo( + widget: ConstrainedBox.Index(), + code: 57709, // low_priority + title: ConstrainedBox.Index.title + ), + ItemInfo( + widget: Wrap.Index(), + code: 59385, // pages + title: Wrap.Index.title + ), + ItemInfo( + widget: Table.Index(), + code: 59568, // receipt + title: Table.Index.title + ), + ItemInfo( + widget: Flow.Index(), + code: 58915, // sd_card + title: Flow.Index.title + ), + ItemInfo( + widget: Stack.Index(), + code: 57795, // settings_system_daydream + title: Stack.Index.title ) ]; diff --git a/lib/widget/regular/stack/demo.dart b/lib/widget/regular/stack/demo.dart new file mode 100644 index 0000000..caed7b6 --- /dev/null +++ b/lib/widget/regular/stack/demo.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; + +class Index extends StatefulWidget { + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + List alignment = [ + Alignment.topLeft, + Alignment.topCenter, + Alignment.topRight, + Alignment.centerLeft, + Alignment.center, + Alignment.centerRight, + Alignment.bottomLeft, + Alignment.bottomCenter, + Alignment.bottomRight + ]; + int alignmentIndex = 5; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('AppBar'),), + body: ListView( + children: [ + SizedBox( + child: Text('修改alignment的值,non-positined节点会改变位置'), + ), + Wrap( + alignment: WrapAlignment.spaceBetween, + children: List.generate(9, (index) { + return FlatButton( + child: Text('${alignment[index]}', style: TextStyle(fontSize: 11.0),), + onPressed: (){ + setState(() { + alignmentIndex = index; + }); + }, + ); + }), + ), + StackDemo(alignmentValue: alignment[alignmentIndex],) + ], + ), + ); + } +} + +class StackDemo extends StatelessWidget { + var alignmentValue; + StackDemo({Key key, @required this.alignmentValue}):super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + textDirection: TextDirection.ltr, + fit: StackFit.loose, + overflow: Overflow.clip, + alignment: alignmentValue, + children: [ + AspectRatio( + aspectRatio: 16/9, + child: Image.network( + 'http://pic1.win4000.com/wallpaper/2019-01-31/5c52bf7fdc959_270_185.jpg', + fit: BoxFit.cover + ), + ), + Positioned( + top: 32.0, + left: 32.0, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '欢聚时代', + style: TextStyle( + fontSize: 20.0, + color: Colors.red, + fontWeight: FontWeight.bold + ), + ), + Text( + 'Efox Team', + style: TextStyle( + fontSize: 14.0, + color: Colors.redAccent + ), + ) + ], + ), + ), + SizedBox( + child: Icon(Icons.ac_unit, color: Theme.of(context).primaryColor, size: 32.0,), + ) + ] + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/stack/index.dart b/lib/widget/regular/stack/index.dart new file mode 100644 index 0000000..4962068 --- /dev/null +++ b/lib/widget/regular/stack/index.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; + +class Index extends StatefulWidget { + static String title = 'Stack'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/Stack-class.html'; + static String mdUrl = 'docs/widget/regular/stack/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index() + ], + ); + } +} diff --git a/lib/widget/regular/table/demo.dart b/lib/widget/regular/table/demo.dart new file mode 100644 index 0000000..0b95617 --- /dev/null +++ b/lib/widget/regular/table/demo.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +class Index extends StatefulWidget { + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Table'),), + body: Center( + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage('http://pic1.win4000.com/wallpaper/2019-01-31/5c52bf7fdc959_270_185.jpg'), + fit: BoxFit.cover + ) + ), + child: Table( + columnWidths: const { + 0: FixedColumnWidth(40.0), + 1: FixedColumnWidth(80.0), + 2: FixedColumnWidth(40.0), + // 3: FixedColumnWidth(80.0) + }, + defaultColumnWidth: FixedColumnWidth(100.0), + textDirection: TextDirection.ltr, + border: TableBorder.all( + width: 1.0, style: BorderStyle.solid, color: Theme.of(context).primaryColor + ), + defaultVerticalAlignment: TableCellVerticalAlignment.top, + // textBaseline: TextBaseline.alphabetic, + children: List.generate(4, (index) { + return TableRow( + children: [ + Container( + height: 50.0, + alignment: Alignment.center, + child: Text('A${index+1}', style: TextStyle(fontSize: 20.0, color: Theme.of(context).primaryColor),), + ), + Container( + height: 50.0, + alignment: Alignment.center, + child: Text('B${index+1}', style: TextStyle(fontSize: 20.0, color: Theme.of(context).primaryColor),), + ), + Container( + height: 50.0, + alignment: Alignment.center, + child: Text('C${index+1}', style: TextStyle(fontSize: 20.0, color: Theme.of(context).primaryColor),), + ), + Container( + height: 50.0, + alignment: Alignment.center, + child: Text('D${index+1}', style: TextStyle(fontSize: 20.0, color: Theme.of(context).primaryColor),), + ), + ] + ); + }) + ), + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/table/index.dart b/lib/widget/regular/table/index.dart new file mode 100644 index 0000000..d6f4768 --- /dev/null +++ b/lib/widget/regular/table/index.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; + +class Index extends StatefulWidget { + static String title = 'Table'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/Table-class.html'; + static String mdUrl = 'docs/widget/regular/table/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index() + ], + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/wrap/demo.dart b/lib/widget/regular/wrap/demo.dart new file mode 100644 index 0000000..e2f31b6 --- /dev/null +++ b/lib/widget/regular/wrap/demo.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; + +class Index extends StatefulWidget { + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + var direction = Axis.horizontal; + var directionValue = 'horizontal'; + var verticalDirection = VerticalDirection.down; + var verticalDirectionValue = 'down'; + var spacing = 10.0; + var runSpacing = 10.0; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Wrap'),), + body: ListView( + children: [ + SizedBox( + child: Text('点击下面值查看变化'), + ), + Wrap( + alignment: WrapAlignment.center, + children: [ + FlatButton( + child: Text('direction:$directionValue', style: TextStyle(fontSize: 11.0),), + onPressed: (){ + setState(() { + direction == Axis.horizontal ? direction = Axis.vertical : direction = Axis.horizontal; + directionValue == 'horizontal' ? directionValue = 'vertical' : directionValue = 'horizontal'; + }); + }, + ), + FlatButton( + child: Text('verticalDirection:$verticalDirectionValue', style: TextStyle(fontSize: 11.0),), + onPressed: (){ + setState(() { + verticalDirection == VerticalDirection.up ? verticalDirection = VerticalDirection.down : verticalDirection = VerticalDirection.up; + verticalDirectionValue == 'up' ? verticalDirectionValue = 'down' : verticalDirectionValue = 'up'; + }); + }, + ), + FlatButton( + child: Text('spacing:$spacing', style: TextStyle(fontSize: 13.0),), + onPressed: (){ + setState(() { + spacing == 10 ? spacing = 15 : spacing = 10; + }); + }, + ), + FlatButton( + child: Text('runSpacing:$runSpacing', style: TextStyle(fontSize: 13.0),), + onPressed: (){ + setState(() { + runSpacing == 10 ? runSpacing = 15 : runSpacing = 10; + }); + }, + ) + ], + ), + Container( + width: double.infinity, + height: 200, + color: Theme.of(context).primaryColor, + child: Wrap( + direction: direction, + alignment: WrapAlignment.center, + spacing: spacing, + runAlignment: WrapAlignment.center, + runSpacing: runSpacing, + crossAxisAlignment: WrapCrossAlignment.start, + textDirection: TextDirection.ltr, + verticalDirection: verticalDirection, + children: List.generate(7, (index) { + return Chip( + avatar: CircleAvatar( + backgroundColor: Theme.of(context).primaryColor, + child: Text('E', style: TextStyle(fontSize: 20.0),), + ), + label: Text('Efox$index'), + ); + }) + ), + ) + ], + ) + ); + } +} \ No newline at end of file diff --git a/lib/widget/regular/wrap/index.dart b/lib/widget/regular/wrap/index.dart new file mode 100644 index 0000000..c117e8a --- /dev/null +++ b/lib/widget/regular/wrap/index.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:efox_flutter/components/widgetComp.dart' as WidgetComp; +import 'demo.dart' as Demo; + +class Index extends StatefulWidget { + static String title = 'Wrap'; + static String originCodeUrl = 'https://docs.flutter.io/flutter/widgets/Wrap-class.html'; + static String mdUrl = 'docs/widget/regular/wrap/index.md'; + @override + _IndexState createState() => _IndexState(); +} + +class _IndexState extends State { + @override + Widget build(BuildContext context) { + return WidgetComp.Index( + title: Index.title, + originCodeUrl: Index.originCodeUrl, + mdUrl: Index.mdUrl, + demoChild: [ + Demo.Index() + ], + ); + } +} \ No newline at end of file diff --git a/locale/en.json b/locale/en.json index dffb8f9..5782a7d 100644 --- a/locale/en.json +++ b/locale/en.json @@ -1,5 +1,5 @@ { - "title": "efox flutter tech app", + "title": "Components", "title_component": "Components", "title_my": "My", "widgetType": { diff --git a/locale/zh.json b/locale/zh.json index 93ab4d8..1c0f4d7 100644 --- a/locale/zh.json +++ b/locale/zh.json @@ -1,5 +1,5 @@ { - "title": "efox flutter教学应用", + "title": "组件", "title_component": "组件", "title_my": "我的", "widgetType": { diff --git a/pubspec.yaml b/pubspec.yaml index f10d1fc..032d6e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,7 @@ dependencies: flutter_markdown: ^0.2.0 flutter_webview_plugin: ^0.3.0+2 fluro: ^1.4.0 + flutter_screenutil: ^0.5.1 dev_dependencies: flutter_test: @@ -63,6 +64,12 @@ flutter: - docs/widget/regular/align/ - docs/widget/regular/center/ - docs/widget/regular/fittedbox/ + - docs/widget/regular/aspectratio/ + - docs/widget/regular/constrainedbox/ + - docs/widget/regular/wrap/ + - docs/widget/regular/table/ + - docs/widget/regular/flow/ + - docs/widget/regular/stack/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.io/assets-and-images/#resolution-aware.