工程结构
图 2 Flutter 工程目录结构
- 我们在 lib 目录下进行 Flutter 代码的开发
- 某些特殊场景下的原生功能,则在对应的 Android 和 iOS 工程中提供相应的代码实现,供对应的 Flutter 代码引用。
工程代码
Flutter 的核心设计思想便是一切皆 Widget。
- 应用
- 视图
- 视图控制器
- 布局
Widget 是组件视觉效果的封装,是 UI 界面的载体,因此我们还需要为它提供一个方法,来告诉 Flutter 框架如何构建 UI 界面,这个方法就是 build。
为什么 StatefulWidget 没有 build()
而 StatelessWidget 有?
这是因为 Widget 需要依据数据才能完成构建,而对于 StatefulWidget 来说,其依赖的数据在 Widget 生命周期中可能会频繁地发生变化。由 State 创建 Widget,以数据驱动视图更新,而不是直接操作 UI 更新视觉属性,代码表达可以更精炼,逻辑也可以更清晰。
整个计数器示例的代码流程示意图:
Widget 只是视图的“配置信息”,是数据的映射,是“只读”的。对于 StatefulWidget 而言,当数据改变的时候,我们需要重新创建 Widget 去更新界面,这也就意味着 Widget 的创建销毁会非常频繁。(Scaffold 应该就是频繁的)
为此,Flutter 对这个机制做了优化,其框架内部会通过一个中间层去收敛上层 UI 配置对底层真实渲染的改动,从而最大程度降低对真实渲染视图的修改,提高渲染效率,而不是上层 UI 配置变了就需要销毁整个渲染视图树重建。
总结
有原生 Android 和 iOS 框架开发经验的同学,可能更习惯命令式的 UI 编程风格:手动创建 UI 组件,在需要更改 UI 时调用其方法修改视觉属性。而 Flutter 采用声明式 UI 设计,我们只需要描述当前的 UI 状态(即 State)即可,不同 UI 状态的视觉变更由 Flutter 在底层完成。