界面开发模式
经典界面编程模式属于响应式,实例化控件并响应控件的事件。譬如响应绘制(OnPaint),鼠标点击(OnClick),重新绘制某个区域(InvalidateRect)。每个控件的消息由操作系统发给该实例。但是Flutter的编程完全不一样了,属于申明式的,Makefile 就属于典型的申明式。
如下典型的界面布局:
经典布局
譬如 Expanded 能够占满整个可能区域,Column 行式布局。
结构体系
申明式只是 Flutter 一个不太重要的特性,但是是最容易理解的,还有很多特性,众多特性才能让 Flutter 拥有足够的优势。要做到申明式并不容易,需要整个体系结构支持。
-) 线程模型。Flutter App有三个主要线程:
- Native 也就是系统的主线程
- Dart VM线程,我们写的Dart代码就运行在这个线程
- “GPU线程”,2D引擎(Skia)运行线程负责控制GPU
- Flutter也会启动其他工作线程负责IO,Image Decode等临时任务
如此规划线程让App开发简单了太多,毕竟不需要关注工作线程和界面线程间的关系、绘制效率。
-) Dart 语言。Dart 几乎是 Closure 闭包最优雅的实现,还有强大的异步支持。
/// 同步读取文件内容 String content = await new File(filePath).readAsString();
异步读取文件
Future<String> inner() {
return new File(filePath).readAsString().then(String cotent) {
print("file content: $content");
});
}
异步调用的跨函数传递是一个难题,Dart的解决方案
Future<Map> outside() {
return inner().then((String content) {
return JSON.decode(content);
});
}
void someFunction() {
outside().then((Map map) {
print("map length: ${map.length}");
});
}
加上异常处理也不会显得麻烦,这里不啰嗦了。这样就能使用闭包处理界面事件了。
界面也有各种 FutureBuilder 等工具解决界面和异步关系。
用好 Future,不使用 await,仅这个策略绝对能让界面不会卡顿,相比几乎所有原生开发者都为卡顿苦恼过。
-) 闭包和嵌套的申明带来一个严重问题就是括号的匹配。没有比 Dart 更优雅的解决方案了。
Dart 提供了 dartfmt 工具来完成格式化,我一般使用的编辑器VSCode。编码过程中一般不会管什么对齐、空格、缩进,写得差不多了就会按一个格式化的快捷键,就完成了格式化。可以说功能一样的代码绝对不会存在第二种格式。Dart 的文档化做得也是没有谁了,可以方便的使用 dartdoc 生成文档。Flutter Team 更是规定了注释、命名等规范,也提供了格式化Java/Objective-C语言,这样整个工程会非常整洁。
-) Flutter很早就在FAQ里说Dart的一个重要特性是生产效率高,我不以为然,但是使用过一段时间dart后,被深深折服了,这货生产效率绝对有保障。
Dart 静态检查
Dart 的静态类型检查做到了极致,超越现有任何一种语言。上图的.name提醒,而下面没有提醒,不用赘述了。
其次自动完成等基础功能几乎所有语言都能做到,更没有说的必要了。
下一篇会说说调试方法、单元测试以及Plugins插件的开发。