Skip to content

Flutter

Flutter 的独特之处是自己渲染一切:不借道系统控件,而是用引擎把 Widget 画到屏幕上,因此跨端像素级一致。主线条:Dart 语言 → Widget 与三棵树 → 状态管理 → 平台通道 → 发布与性能。示例基于 Flutter 3.x 稳定线编写,需在安装 Flutter SDK 的环境验证。

Flutter 是什么:三层架构

内容类比
Framework(Dart)Widget、布局、动画、手势、Material/Cupertino你写代码的地方
Engine(C++)渲染(Impeller/Skia)、文本、平台通道、Dart VM系统之上的一层「画布」
Embedder与 iOS/Android/桌面原生宿主桥接每个平台各一套薄壳

关键推论:渲染不依赖系统控件,所以两端 UI 一致、动画可控;代价是引擎体积与首帧成本、部分系统级能力要走通道。

Dart 语言速览(够用就好)

  • 一切皆对象,类型可空(String?),final/const 优先;
  • 集合:List/Set/Map;集合字面量简洁;
  • 异步:Future/async/await + Stream(流,适合事件序列);
  • 类:构造器语法、factorynamed 参数、不可变推荐 const 构造;
  • Flutter 运行时无反射常规用(tree-shaking),JSON 解析手写或 codegen(json_serializable/freezed)。
dart
Future<void> fetchUsers() async {
  final resp = await http.get(Uri.parse('https://api.example.com/users'));
  final list = jsonDecode(resp.body) as List;
  // list.map(...) 转模型
}

Widget 与「三棵树」

Widget 只是配置描述(不可变),真正干活的是它背后的树:

  1. Widget 树:你写的声明(每次 rebuild 都新建);
  2. Element 树:Widget 与 RenderObject 的粘合,负责 diff(框架帮你维护);
  3. RenderObject 树:真正布局/绘制。

所以放心写 build——Flutter 只对有变化的部分重建 Element,而不是每次整体重绘。

状态组件两种写法

dart
// 无状态
class Greeting extends StatelessWidget {
  const Greeting({super.key, required this.name});
  final String name;

  @override
  Widget build(BuildContext context) => Text('你好,$name');
}

// 有状态
class Counter extends StatefulWidget {
  const Counter({super.key});
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    return FilledButton(
      onPressed: () => setState(() => _count++),
      child: Text('次数 $_count'),
    );
  }
}

注意:Widget 重建(父级 rebuild)不等于 State 丢失——State 附着在 Element 上,用 key 控制是否复用/重建 State。

布局速查

场景组件
纵向/横向排布Column / Row(主轴对齐、Expanded 占位)
叠放Stack
容器装饰ContainerDecoratedBox
滚动列表(懒加载)ListView.builder / GridView.builder
自适应尺寸FlexibleAspectRatioLayoutBuilder
安全区SafeAreaMediaQuery
对齐与间距PaddingAlignSpacerSizedBox

核心习惯:小屏高复用组件都写成 const 构造(const Text(...)),让重建跳过。

状态管理谱系(从简到繁)

方案适合备注
setState单个组件内最基础,别到处搬
ValueNotifier + ValueListenableBuilder单个全局小状态轻量
InheritedWidget / Provider少量跨层共享官方推荐的入门层级
Riverpod中大型、追求类型安全与可测试当前社区主流推荐之一
Bloc重逻辑、事件驱动团队样板多,规则明确

选型建议:小项目 Provider 起步;项目明显增长或多人协作再迁移 Riverpod/Bloc,不要一上来上最重的。页面级请求状态 + 全局会话/主题是两种状态,分层管理(见本站分层纪律)。

导航路由

  • Navigator.push(MaterialPageRoute(...)) 命令式跳转;
  • 命名路由/go_router(声明式深链、守卫),App 复杂后用 go_router
  • 传参用构造参数或路由参数对象;回传结果用 Navigator.pop(context, result)

与原生交互:平台通道

  • MethodChannel:Dart 调原生方法(平台侧写同名字符串方法);
  • 更现代的 Pigeon:生成类型安全通道代码,减少字符串拼写错误;
  • dart:ffi:需要极高性能时直接绑 C 库;
  • 推荐顺序:优先找维护良好的官方/知名插件(如 shared_preferencespath_providerimage_picker),确实没有再自己写通道。

平台侧别忘了:iOS 的 Info.plist 权限文案、Android 的 Manifest 权限与 ProGuard 配置常是「插件装上却不工作」的元凶。

依赖与工程

  • pubspec.yaml 管理依赖;flutter pub add xx 添加;
  • flutter analyze(静态检查)+ dart format 进 CI;
  • 测试:test 单测、widget_test Widget 测试、integration_test 真机/模拟器端到端;
  • 环境区分:--dart-define=API_BASE_URL=... 注入环境变量,String.fromEnvironment 读取。

发布

bash
flutter build apk --release            # Android APK
flutter build appbundle --release      # Android AAB(上 Play 用)
flutter build ios --release            # iOS(需 macOS + 签名)
flutter build windows / macos / linux  # 桌面(各自系统)

iOS 仍要走证书/TestFlight 流程、Android 仍要签名,见打包、签名与发布;桌面端参考桌面应用:Electron / Tauri

性能与调试(详见性能与稳定性

  • 帧预算:Flutter 目标是 60/120fps,动画掉帧先开 DevTools 的 performance 看耗时区间(build/layout/paint);
  • const 构造 + RepaintBoundary 减少重绘范围;
  • 图片:cached_network_image/平台缓存,列表图用缩略图尺寸;
  • 列表:ListView.builder 懒加载,不要 ListView(children:) 塞上千项;
  • 热重载(r)改代码、热重启(R)改 main/全局状态,调试两件套。

常见坑速查

现象对策
忘加 const大量 rebuild 性能浪费、lint 警告小叶子组件尽量 const
布局溢出RenderFlex overflowed 黄黑条Row/Column 里给可伸缩项加 Expanded/Flexible
列表用错一次性建上千 View 卡死一律 builder 系列懒加载
原生插件缺配置Android/iOS 平台报错或空白先查 Info.plist / Manifest 权限与混淆
状态管理搬全家组件间乱传回调难维护状态就近 + 按层治理
JSON 手写解析崩字段类型不符运行时炸freezed/json_serializable + 单元测试
文本缩放溢出系统大字体下 UI 溢出测试大字体,用 Flexible/ellipsis
跨端像素差异部分平台字体/滚动条观感不同每端真机回归 UI 清单
版本升级裸奔升级 Flutter 后插件不兼容用官方 upgrade 指南按小版本渐进
发布包不含环境区分打到生产误用测试环境dart-define 注入 + 构建产物校验
忘记处理空值/空列表无数据时白屏或崩统一 empty/error/loading 三态组件

检查清单

  • [ ] 布局组件用对了(列表用 builder,溢出用 Flexible);
  • [ ] 状态分层明确:页面级 + 全局级分开治理;
  • [ ] 原生能力优先找官方插件,自写通道用 Pigeon 类型安全方案;
  • [ ] 平台侧权限/文案/混淆已配置;
  • [ ] flutter analyze 与测试在 CI 通过;
  • [ ] release 构建可出包,环境变量隔离正确;
  • [ ] 真机过一遍大字体、横竖屏、弱网三回归。

相关链接:技术全景与选型 · React Native · 性能与稳定性 · 打包、签名与发布 · 写作规范见客户端开发索引

基于 VitePress 构建 · 内容以知识共享方式沉淀