… 延展操作符( ...
)可以对数组或者字典进行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 test1() { var list = [1 , 2 , 3 ]; var list2 = [0 , ...list, 4 ]; print (list2); } test2() { var map1 = { "key1" : "value1" , "key2" : "value2" , }; var map2 = { "key3" : "value3" , "key4" : "value4" , }; var map3 = {...map1, ...map2}; print (map3); }
for ()…[] 合并 widgets 到集合中,使用 for ()...[]
范式,使用延展操作符( ...
)来合并一个数组的 widgets 到一个存在的集合中。例如在构造 Row 或者 Column 的 children 时,非常方便。下面是示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 List <Food> foods = [ Food(name: 'apple' , isVegetarian: true ), Food(name: 'nuts' , isVegetarian: true ), Food(name: 'eggs' , isVegetarian: true ), Food(name: 'chicken' , isVegetarian: false ), ]; class Food { Food({ this .name, this .isVegetarian, }); String name; bool isVegetarian; } class HomePage extends StatelessWidget { const HomePage({Key key}) : super (key: key); @override Widget build(BuildContext context) { return Container( child: Column( children: [ Container(), for (final food in foods) ...[ if (food.isVegetarian) ListTile(title: Text(food.name)), SizedBox(height: 50.0 ), ], ], ), ); }
() {} () 立即执行一个匿名函数: () {} ()
,相当于声明一个匿名函数并且里面执行,这种范式在处理一个 widget 可能有多种输出时特别有用。而不是使用镶嵌的三目运算符或者通过一个函数调用,这个代码跟内联。下面是示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 T getRandomElement<T>(List <T> list) => list[Random().nextInt(list.length)]; Column( children: [ Container( color: () { switch (getRandomElement(foods).name) { case 'apple' : return Colors.green; case 'nuts' : return Colors.brown; case 'eggs' : return Colors.yellow; default : return Colors.transparent; } }(), child: Text('Food of the Day' ), ), ], )
代码静态分析 在提交代码时为了提高代码质量,保持团队的代码风格一致,需要进行代码静态分析,一般通过下面 2 种方法来进行
flutter analyze 使用 flutter analyze
进行代码静态分析,此命令会根据 analysis_options.yaml
定义的规则进行静态分析
dartfmt 使用 dartfmt ./ -w
对当前目录以及子目录的 dart 代码进行代码, -w
选项会自动重写文件使其符合规范。
使用 dartfmt ./ -n
显示当前目录以及子目录的 dart 代码格式可以修改的文件但是不做修改,可以配合 ci 分析代码格式问题。
更多选项请使用 dartfmt --help
查看
Push & present & Pop 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Navigator.pushNamed(context, '/b' ) Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => MyPage())); Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => MyPage(),fullscreenDialog: true )); Navigator.pop(context) Navigator.of(context) ..pop() ..pop() ..pushNamed('/settings' );
API
1 2 3 4 5 6 7 8 9 Future push(BuildContext context, Route route) bool pop(BuildContext context, [ result ]) Navigator.push(BuildContext context, Route route) Navigator.of(context).push(Route route)
1 2 3 final RenderBox box = keyContext.findRenderObject();final size = box.size;final topLeftPosition = box.localToGlobal(Offset.zero);
See more
Model To JSON json_serializable
引入
1 2 3 4 5 6 7 8 dependencies: json_annotation: ^2.0.0 dev_dependencies: build_runner: ^1.0.0 json_serializable: ^2.0.0
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import 'package:json_annotation/json_annotation.dart' ;part 'user.g.dart' ;@JsonSerializable ()class User { User(this .name, this .email); String name; String email; factory User.fromJson(Map <String , dynamic > json) => _$UserFromJson(json); Map <String , dynamic > toJson() => _$UserToJson(this ); }
单次解析: flutter packages pub run build_runner build
4. 持续集成: flutter packages pub run build_runner watch
5. json_serializable 在线 json 转 dart model 工具
Built value
在线 json 转 build value 模板工具 https://charafau.github.io/json2builtvalue/
VSCode built value 插件
Sample code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 import 'package:built_value/built_value.dart' ;part 'user.g.dart' ;abstract class User implements Built <User , UserBuilder > { String get name; @nullable String get nickname; User._(); factory User([updates(UserBuilder b)]) = _$User; } var user1 = new User((b) => b ..name = 'John Smith' ..nickname = 'Joe' ); var user2 = user.rebuild((b) => b ..nickname = 'Jojo' ); var updatedStructuredData = structuredData.rebuild((b) => b ..user.update((b) => b ..name = 'Johnathan Smith' ) ..credentials.phone.update((b) => b ..country = Country.switzerland ..number = '555 01234 555' )); abstract class Node implements Built <Node , NodeBuilder > { @nullable String get label; @nullable Node get left; @nullable Node get right; Node._(); factory Node([updates(NodeBuilder b)]) = _$Node; } var node = new Node((b) => b ..left.left.left.right.left.right.label = 'I’m a leaf!' ..left.left.right.right.label = 'I’m also a leaf!' ); var updatedNode = node.rebuild((b) => b ..left.left.right.right.label = 'I’m not a leaf any more!' ..left.left.right.right.right.label = 'I’m the leaf now!' );
参考