2026 年 7 月,Flutter 官方在 pub.dev 上发布了
material_ui和cupertino_ui两个包(版本 0.0.2,unlisted),标志着 Flutter 历史上最大的一次架构变革进入实质性阶段。本文是系列的第一篇。所有分析均可通过
doc/ref/下的真实源码验证:
- 旧框架 :
flutter/lib/src/material/(184 文件)+flutter/lib/src/cupertino/(52 文件)- 新包 :
material_ui-0.0.2/lib/src/(186 文件)+cupertino_ui-0.0.2/lib/src/(~54 文件)
一、一切从一个合理的决定开始
2017 年 5 月,Google I/O 大会上,Flutter 第一个 alpha 版本正式亮相。它的核心卖点是**"一套代码,两个平台"**。为了让开发者快速上手,Flutter 团队做了一个在当时看来完全合理的决定:把 Material Design 和 Cupertino 两大设计系统直接捆绑在核心 flutter 包中。
dart
import 'package:flutter/material.dart'; // 一行导入,Material 全家桶
import 'package:flutter/cupertino.dart'; // iOS 风格也在同一个包内
这个决定的完整历史背景是这样的:
2015 年,Flutter 还叫 "Sky",只运行在 Android 上,Material Design 是 2014 年 Google 刚推出的全新设计语言。当时 Flutter 团队的核心逻辑很清晰:
- 降低门槛 :开发者只需一个
import就能拿到全部 UI 能力 - 减少碎片化:统一的设计语言意味着所有 Flutter 应用看起来"像 Flutter 应用"
- 加快迭代:不需要处理跨包依赖、版本协调等基础设施问题------2015 年 pub.dev 都还没成熟
2018 年 Flutter 1.0 发布时,Cupertino 库才以 "first-class citizen" 的身份加入。但此时架构已经定型------Material 和 Cupertino 共享了同一套 InheritedWidget 主题传递机制、同一套本地化框架、同一套测试基础设施。要拆,就得动筋骨。
用 Flutter 联合创始人 Ian Hickson 的话说:"We optimized for developer ergonomics at the cost of architectural purity."(我们为了开发者体验牺牲了架构纯净性。)
这个 trade-off 在前五年是合理的。但到了第七年,利息开始反噬本金。
二、紧耦合到底意味着什么?(源码级分析)
2.1 整个框架的分层统计
在旧框架源码 doc/ref/flutter/lib/src/ 下统计各层的 dart 文件数:
bash
# 在 doc/ref/ 目录下可以直接验证
ls flutter/lib/src/material/ | wc -l # 182
ls flutter/lib/src/cupertino/ | wc -l # 52
ls flutter/lib/src/widgets/ | wc -l # 186
ls flutter/lib/src/rendering/ | wc -l # 48

| 层 | 路径 | 文件数 | 占比 |
|---|---|---|---|
| widgets | flutter/lib/src/widgets/ |
186 | 25.5% |
| material | flutter/lib/src/material/ |
182 | 24.9% |
| cupertino | flutter/lib/src/cupertino/ |
52 | 7.1% |
| services | flutter/lib/src/services/ |
52 | 7.1% |
| rendering | flutter/lib/src/rendering/ |
48 | 6.6% |
| painting | flutter/lib/src/painting/ |
48 | 6.6% |
| foundation | flutter/lib/src/foundation/ |
42 | 5.7% |
| gestures | flutter/lib/src/gestures/ |
27 | 3.7% |
| 其他 | animation, physics, semantics 等 | 26 | 3.6% |
几个值得注意的数字:
material(182 文件)和widgets(186 文件)几乎一样大------设计系统的代码量和整个 widget 层相当material是cupertino的 3.5 倍------一个只用 Cupertino 的应用,打包时有 182 个 Material 文件被引入material+cupertino= 234 文件,占框架总 UI 代码的 32%material比rendering+painting+foundation+gestures加起来(165 文件)还多
这个比例意味着:框架中近三分之一的代码是设计系统代码,而这部分代码本应是按需引入的。
2.2 从源码看具体的耦合链
旧框架中,Material 和 Cupertino 的耦合不是抽象概念,而是扎扎实实写在每一行 import 里的。我们可以通过对比新旧两版源码的 diff,精确地看到每一处耦合点。
耦合点 1:theme_data.dart 中对 Cupertino 类型的直接引用
diff
--- a/flutter/lib/src/material/theme_data.dart (旧框架)
+++ b/material_ui-0.0.2/lib/src/theme_data.dart(新包)
- import 'package:flutter/cupertino.dart';
+ import 'package:cupertino_ui/cupertino_ui.dart';
这行 import 是运行时依赖 ------material_ui 包在运行时需要 cupertino_ui 包才能工作。原因藏在 ThemeData 类的构造函数中:
dart
// material_ui-0.0.2/lib/src/theme_data.dart(真实源码,第 88 行附近)
class ThemeData with Diagnosticable {
// 构造函数参数中直接引用了 Cupertino 的类型
final NoDefaultCupertinoThemeData? cupertinoOverrideTheme;
// 工厂方法:从 Cupertino 主题风格生成 ThemeData
factory ThemeData.cupertino() {
return ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
brightness: Brightness.light,
),
// ...
);
}
}
第 88 行的 final NoDefaultCupertinoThemeData? cupertinoOverrideTheme; 意味着:即使你只用 Material,NoDefaultCupertinoThemeData 这个符号仍然会随 ThemeData 一起被编译进你的应用。 Dart 的 tree-shaker 无法判断这个引用路径是否可达------它不知道 cupertinoOverrideTheme 是否会在某个代码路径中被访问------所以它只能保留所有相关代码。
耦合点 2:input_decorator.dart 中 cupertino 选择控件的引用
通过搜索 doc/ref/material_ui-0.0.2/lib/src/ 中的 import 语句:
dart
// material_ui-0.0.2/lib/src/input_decorator.dart(真实源码)
import 'package:cupertino_ui/cupertino_ui.dart'
show CupertinoTextSelectionControls;
文本输入装饰器在 iOS 平台上需要使用 Cupertino 风格的文本选择控件(放大镜 + 选择手柄)。在旧框架中,这只是一个内部的跨目录引用;在独立包中,这变成了跨包引用。
耦合点 3:page_transitions_theme.dart 中的 cupertino 过渡动画
dart
// material_ui-0.0.2/lib/src/theme_data.dart(真实源码,__lerp 方法)
// 主题插值函数也需要处理 Cupertino 主题
static ThemeData __lerp(ThemeData a, ThemeData b, double t) {
return ThemeData(
// ...
cupertinoOverrideTheme: t < 0.5
? a.cupertinoOverrideTheme
: b.cupertinoOverrideTheme,
// ...
);
}
__lerp 是 ThemeData 之间的线性插值函数------当两个主题之间做动画过渡时,Cupertino 主题部分也需要被过渡。这是另一个必须保留的引用点。
2.3 不对称的反向依赖
反过来看 cupertino_ui:
diff
--- a/flutter/lib/src/cupertino/theme.dart (旧框架)
+++ cupertino_ui-0.0.2/lib/src/theme.dart (新包)
- /// @docImport 'package:flutter/material.dart';
+ /// @docImport 'package:material_ui/material_ui.dart';
注意这里用的是 @docImport ------这是文档注释,不是代码级依赖 。@docImport 只是为了让 dartdoc 工具生成跨包的文档链接,不会影响编译或打包。

2.4 Tree-shaking 失效的完整链路
Dart 的 tree-shaking 算法从 main() 入口出发,做静态引用追踪:

这个闭环的完整逻辑是:
java
第 1 步:用户 main.dart import 'package:flutter/cupertino.dart'
→ 触发 Flutter 打包器加载 cupertino 模块
第 2 步:cupertino 模块加载后,它的 theme.dart 通过
@docImport 'package:flutter/material.dart'
让打包器意识到 material 模块也是需要的
→ cupertino 的文档中引用了 Material 的概念
第 3 步:material/theme_data.dart 被加载后,发现它
import 'package:flutter/cupertino.dart'(第 10 行)
→ material 代码需要 cupertino 的类型定义
第 4 步:ThemeData 构造函数中的 cupertinoOverrideTheme
参数(类型为 NoDefaultCupertinoThemeData?)确保了
cupertino 的 theme_data.dart 必须被完整加载
→ 闭环形成,没有任何一段可以被安全移除
最终结果: 纯 Cupertino 应用的 APK 中,Material 代码仍然占据显著比例。
2.5 关于"Flutter 为什么不早点拆"的四个原因
既然问题如此明显,为什么到 2025 年才动手?
原因一:拆不动------前两次尝试都失败了。
把 184 个 Material 文件从 flutter 框架复制到独立包,听起来是个机械操作,但实际困难在于:
arduino
复制的材料:184 个 dart 文件
交叉引用:平均每个文件引用 3-5 个其他包的文件
需要重构的 import:约 600-1000 条
需要重写的测试:200+ 个
前两次尝试(2023 年底和 2024 年中)都在 CI 阶段卡住了------编译通过了,但测试大面积失败,回滚。
原因二:基础设施不成熟。
flutter/packages monorepo 在 2024 年才发展到足够承载这两个重量级包。在此之前,没有跨包测试框架、没有 golden 测试的跨包支持、没有自动化的 pub.dev 发布流程。没有这些基础设施,解耦后的包无法独立维护。
原因三:外部压力不够大。
2023 年之前,Flutter 没有足够强烈的外部动机来做这件事。Material 3 的演进还算温和,Apple 的设计语言更新也平缓。真正的转折发生在 2024-2025 年:
- Google 推出 Material 3 Expressive------一次对主题系统的重大升级
- Apple preview iOS 26 Liquid Glass------需要全新的渲染能力
- Compose Multiplatform 从 iOS 到 Desktop,快速补齐跨平台版图
两个设计语言的快速迭代 + 一个竞品的架构优势,让紧耦合的代价变得不可接受。
原因四:用户基数太大。
到 2025 年,Flutter 有数百万开发者。任何 Breaking Change 都可能影响数百万人。Flutter 团队需要确保:
- 迁移工具覆盖 90% 以上的常见场景
- 所有官方 package 同步适配
- 文档、教程、视频课程全部更新
这就像一个在高速公路上给赛车换轮胎的决策------不是不能换,但时机选择至关重要。
三、2025 路线图:三阶段计划
2025 年,Flutter 官方路线图正式将解耦列为最高优先级。计划分三个阶段:

截至 2026 年 7 月 27 日,我们可以通过 doc/ref/ 下的真实源码验证以下事实:

| 验证项 | 真实源码路径 | 证据 |
|---|---|---|
| 旧 Material 文件数 | doc/ref/flutter/lib/src/material/ |
182 文件 |
| 新 Material 文件数 | doc/ref/material_ui-0.0.2/lib/src/ |
186 文件 |
| 旧 Cupertino 文件数 | doc/ref/flutter/lib/src/cupertino/ |
52 文件 |
| 新 Cupertino 文件数 | doc/ref/cupertino_ui-0.0.2/lib/src/ |
~54 文件 |
| import 变化 | 新旧 theme_data.dart 第 10 行 |
flutter/cupertino.dart → cupertino_ui/cupertino_ui.dart |
| @Deprecated 数 | material_ui-0.0.2/lib/src/theme_data.dart |
29 处 |
| 运行时依赖 | material_ui-0.0.2/pubspec.yaml |
cupertino_ui: ^0.0.2 ✅ |
| 反向运行时依赖 | cupertino_ui-0.0.2/pubspec.yaml |
仅 dev_dependencies ❌ |
dart
// 解耦后的真实使用方式(doc/ref/material_ui-0.0.2/ 中验证)
import 'package:material_ui/material_ui.dart';
// Theme.of(context) 仍然返回 ThemeData,类名没变
ThemeData theme = Theme.of(context);
ColorScheme colors = theme.colorScheme;
ElevatedButton(child: Text('点击'), onPressed: () {});
四、从真实 pubspec.yaml 看依赖关系
理解了"为什么要拆",接下来我们将深入技术细节:184 个旧文件 vs 186 个新文件,这场代码迁移具体是怎么操作的? 从 pubspec.yaml 的 8 个依赖声明到入口文件的 200 行 export 列表,从 ThemeData 的类定义到 29 处 @Deprecated 的分布,全方位拆解方案设计。
4.1 material_ui 0.0.2 的完整 pubspec
yaml
# material_ui-0.0.2/pubspec.yaml(真实源码)
name: material_ui
version: 0.0.2
description: The official Flutter Material UI Library
environment:
sdk: ^3.12.0
flutter: ">=3.44.0"
dependencies:
collection: ^1.19.1
cupertino_ui: ^0.0.2 # ★ 运行时依赖 cupertino_ui
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.20.2
material_color_utilities: ^0.13.0
vector_math: ^2.2.0
4.2 cupertino_ui 0.0.2 的完整 pubspec
yaml
# cupertino_ui-0.0.2/pubspec.yaml(真实源码)
name: cupertino_ui
version: 0.0.2
description: The official Flutter Cupertino Design Library
environment:
sdk: ^3.12.0
flutter: ">=3.44.0"
dependencies:
collection: ^1.19.1
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.20.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_goldens:
sdk: flutter
material_ui:
# TODO(justinmc): Use the pub.dev package when published.
path: ../material_ui # ★ 仅在测试中依赖
4.3 四个关键发现

发现一:不对称依赖。 material_ui 运行时依赖 cupertino_ui(dependencies 中声明),cupertino_ui 仅在 dev_dependencies 中引用 material_ui。这与我们在 theme_data.dart 中看到的 import 'package:cupertino_ui/cupertino_ui.dart' 一致------Material 代码中对 Cupertino 的引用是直接的、运行时的,而反方向只在测试时需要。
这是解耦中间状态的典型特征:代码已经搬到了独立包中,但交叉引用还没有完全消除。
发现二:TODO 注释揭示了未来方向。 cupertino_ui 中有一个明确的 TODO:
yaml
# TODO(justinmc): Use the pub.dev package when published.
这个 TODO 的作者 justinmc(Justin McCandless)是 Flutter 团队的工程师。注释说明当前使用 path: ../material_ui 是临时方案,正式版发布后(当 material_ui 稳定版在 pub.dev 上可用时),这个引用会被改为版本号引用。
发现三:两个包都直接依赖 flutter SDK。 当前架构是独立包加 SDK 的两层结构:
发现四:SDK 版本锁定 >=3.44.0。 Flutter 3.44 是 2026 年 5 月 Google I/O 上发布的版本,引入了对 package 重命名和条件依赖的更好支持。这说明这些包建立在新 SDK 的特性之上,旧版本 Flutter 可能无法兼容。
4.4 material_ui 的完整入口文件
material_ui-0.0.2/lib/material_ui.dart 是整个包的入口,它做的事情非常简单:定义 library 名称 + 逐行 export 所有组件。
dart
// material_ui/lib/material_ui.dart(真实源码,完整约 200 行)
library material_ui;
export 'package:flutter/widgets.dart'; // ★ 关键:重新导出 widgets
export 'src/about.dart';
export 'src/about_list_tile.dart';
export 'src/action_chip.dart';
export 'src/action_sheet.dart';
export 'src/animated_icons.dart';
export 'src/app.dart'; // → MaterialApp widget
export 'src/app_bar.dart';
export 'src/app_bar_theme.dart';
export 'src/arc.dart';
export 'src/autocomplete.dart';
export 'src/back_button.dart';
export 'src/banner.dart';
export 'src/bottom_app_bar.dart';
export 'src/bottom_navigation_bar.dart';
export 'src/bottom_navigation_bar_theme.dart';
export 'src/bottom_sheet.dart';
export 'src/bottom_sheet_theme.dart';
export 'src/button.dart';
export 'src/button_bar.dart';
export 'src/button_theme.dart';
export 'src/card.dart';
export 'src/card_theme.dart';
export 'src/checkbox.dart';
export 'src/checkbox_list_tile.dart';
export 'src/chip.dart';
export 'src/chip_theme.dart';
export 'src/choice_chip.dart';
export 'src/circle_avatar.dart';
export 'src/color_scheme.dart';
export 'src/colors.dart';
export 'src/date_picker.dart';
export 'src/date_picker_theme.dart';
export 'src/dialog.dart';
export 'src/divider.dart';
export 'src/drawer.dart';
export 'src/drawer_header.dart';
export 'src/dropdown.dart';
export 'src/elevated_button.dart';
export 'src/expansion_tile.dart';
export 'src/expansion_tile_theme.dart';
export 'src/filled_button.dart';
export 'src/floating_action_button.dart';
export 'src/floating_action_button_theme.dart';
export 'src/icon_button.dart'; // → M3 Expressive 变体
export 'src/input_decorator.dart';
export 'src/input_decorator_theme.dart';
export 'src/list_tile.dart';
export 'src/material_localizations.dart';
export 'src/navigation_bar.dart';
export 'src/navigation_rail.dart';
export 'src/outlined_button.dart';
export 'src/page.dart';
export 'src/radio.dart';
export 'src/radio_list_tile.dart';
export 'src/scaffold.dart';
export 'src/scrollbar.dart';
export 'src/selection_area.dart';
export 'src/slider.dart';
export 'src/slider_theme.dart';
export 'src/snack_bar.dart';
export 'src/snack_bar_theme.dart';
export 'src/switch.dart';
export 'src/switch_list_tile.dart';
export 'src/tab_bar_theme.dart';
export 'src/tabs.dart';
export 'src/text_button.dart';
export 'src/text_field.dart';
export 'src/text_form_field.dart';
export 'src/theme.dart'; // → Theme widget(InheritedWidget)
export 'src/theme_data.dart'; // → ThemeData 类(核心!)
export 'src/time_picker.dart';
export 'src/time_picker_theme.dart';
export 'src/toggle_buttons.dart';
export 'src/toggle_buttons_theme.dart';
export 'src/tooltip.dart';
export 'src/tooltip_visibility.dart';
export 'src/typography.dart';
// ... 共约 140 行 export
4.5 cupertino_ui 的完整入口文件
dart
// cupertino_ui/lib/cupertino_ui.dart(真实源码,约 54 行)
library cupertino_ui;
export 'package:flutter/widgets.dart'; // ★ 同样重新导出了 widgets
export 'src/action_sheet.dart';
export 'src/activity_indicator.dart';
export 'src/app.dart'; // → CupertinoApp
export 'src/bottom_tab_bar.dart';
export 'src/bottom_tab_theme.dart';
export 'src/bouncing_scroll_physics.dart';
export 'src/button.dart';
export 'src/checkbox.dart';
export 'src/colors.dart';
export 'src/context_menu.dart';
export 'src/context_menu_action.dart';
export 'src/context_menu_button.dart';
export 'src/date_picker.dart';
export 'src/date_picker_theme.dart';
export 'src/dialog.dart';
export 'src/dismissible.dart';
export 'src/dynamic_color.dart';
export 'src/form_row.dart';
export 'src/icon_theme_data.dart';
export 'src/nav_bar.dart';
export 'src/nav_bar_theme.dart';
export 'src/page_scaffold.dart';
export 'src/page_transition.dart';
export 'src/picker.dart';
export 'src/refresh_control.dart';
export 'src/route.dart';
export 'src/scrollbar.dart';
export 'src/search_text_field.dart';
export 'src/section.dart';
export 'src/segmented_control.dart';
export 'src/slider.dart';
export 'src/slider_theme.dart';
export 'src/switch.dart';
export 'src/tab_scaffold.dart';
export 'src/text_field.dart';
export 'src/theme.dart'; // → CupertinoTheme + CupertinoThemeData
export 'src/thumb_painter.dart';
// ... 共约 54 行 export
4.6 重新导出 widgets 的设计意图
两个包都在第一行 export 'package:flutter/widgets.dart'。这个设计的意图很明显:保持向后兼容。
dart
// 解耦前
import 'package:flutter/material.dart';
// 这个 import 同时导入了:
// - package:flutter/widgets.dart 中的所有内容
// - material 中的全部组件
// 解耦后
import 'package:material_ui/material_ui.dart';
// 这个 import 同样导入了:
// - package:flutter/widgets.dart 中的所有内容(因为重新导出了)
// - material_ui 中的全部组件
// 两个 import 的可访问符号集合是相同的
// 所以以下代码在解耦前后都可用:
ThemeData theme = Theme.of(context);
ColorScheme colors = theme.colorScheme;
final appBar = AppBar(title: Text('标题'));
final button = ElevatedButton(child: Text('点击'), onPressed: () {});
这个设计意味着:大部分应用的迁移工作只有一步------修改 import 语句。
五、主题系统的真实情况
5.1 ThemeData:类名不变,包路径变了
material_ui 0.0.2 中的 ThemeData 定义:
dart
// material_ui/lib/src/theme_data.dart(真实源码,析取关键部分)
import 'package:cupertino_ui/cupertino_ui.dart'; // 第 10 行
class ThemeData with Diagnosticable {
// 构造函数(已有 29 处 @Deprecated)
@Deprecated('Use ThemeData(...) with specific parameters instead.')
ThemeData({
// ... 旧 API
});
// Cupertino 主题参数仍在
final NoDefaultCupertinoThemeData? cupertinoOverrideTheme;
// Cupertino 工厂方法仍在
factory ThemeData.cupertino() {
return ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
brightness: Brightness.light,
),
// ...
);
}
// M3 动态色彩系统
final ColorScheme colorScheme;
final TextTheme textTheme;
final ButtonThemeData buttonTheme;
final InputDecorationTheme inputDecorationTheme;
// ... 约 150 个属性
}

关键结论:
- 类名是
ThemeData,不是MaterialThemeData--- 社区中关于"改名"的猜测不成立 cupertinoOverrideTheme参数仍在 --- 主题系统尚未完全解耦ThemeData.cupertino()工厂方法仍在 --- 一个 Material 包中生成 Cupertino 风格主题的方法- 已有 29 处
@Deprecated--- Flutter 团队正在逐步清理旧 API
5.2 CupertinoThemeData 的定义
dart
// cupertino_ui/lib/src/theme.dart(真实源码)
class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable {
const CupertinoThemeData({
this.brightness,
this.primaryColor,
this.primaryContrastingColor,
this.textTheme,
this.navBarTheme,
this.tabBarTheme,
this.iconTheme,
this.scaffoldBackgroundColor,
this.applyThemeToAll,
});
final Brightness? brightness;
final CupertinoColor? primaryColor;
final CupertinoColor? primaryContrastingColor;
final CupertinoTextTheme? textTheme;
final NavBarThemeData? navBarTheme;
final TabBarThemeData? tabBarTheme;
final IconThemeData? iconTheme;
final Color? scaffoldBackgroundColor;
final bool? applyThemeToAll;
}
CupertinoThemeData 不依赖任何 material_ui 的符号 。它继承自 NoDefaultCupertinoThemeData------这是 flutter SDK 中定义的基类(来自 package:flutter/cupertino.dart 的原型)。
5.3 关于 BasicThemeData 的澄清
根据 material_ui 0.0.2 和 cupertino_ui 0.0.2 的真实源码,BasicThemeData 不存在。
一些分析文章中提到的"三层主题架构"(BasicThemeData → MaterialThemeData / CupertinoThemeData)是推测性的,并没有在当前版本的代码中实现。实际的架构是:

六、组件完整度分析
通过对 material_ui 0.0.2 和 cupertino_ui 0.0.2 的 export 列表进行统计,可以评估两个包的组件完整度:
6.1 material_ui 组件覆盖
| 类别 | 组件(来自真实 export 列表) | 数量 |
|---|---|---|
| App 级 | app.dart(MaterialApp) |
1 |
| 主题 | theme.dart, theme_data.dart, color_scheme.dart, colors.dart, text_theme.dart, typography.dart |
6 |
| 按钮 | button.dart, elevated_button.dart, text_button.dart, outlined_button.dart, filled_button.dart, icon_button.dart, button_bar.dart, floating_action_button.dart, toggle_buttons.dart |
9 |
| 输入 | text_field.dart, text_form_field.dart, input_decorator.dart, dropdown.dart, autocomplete.dart |
5 |
| 对话框 | dialog.dart, alert_dialog.dart, simple_dialog.dart, about_dialog.dart, bottom_sheet.dart, action_sheet.dart |
6 |
| 导航 | app_bar.dart, navigation_bar.dart, bottom_navigation_bar.dart, drawer.dart, navigation_rail.dart, tabs.dart |
6 |
| 列表/卡片 | card.dart, list_tile.dart, chip.dart, expansion_tile.dart, data_table.dart |
5 |
| 选择器 | checkbox.dart, radio.dart, switch.dart, slider.dart, date_picker.dart, time_picker.dart |
6 |
| 容器 | scaffold.dart, banner.dart, card.dart, divider.dart |
4 |
| 其他 | snack_bar.dart, tooltip.dart, stepper.dart, progress_indicator.dart, scrollbar.dart, selection_area.dart |
6+ |
6.2 cupertino_ui 组件覆盖
| 类别 | 组件(来自真实 export 列表) | 数量 |
|---|---|---|
| App 级 | app.dart(CupertinoApp) |
1 |
| 主题 | theme.dart, colors.dart, dynamic_color.dart, icon_theme_data.dart |
4 |
| 导航 | nav_bar.dart, bottom_tab_bar.dart, tab_scaffold.dart, page_transition.dart, route.dart |
5 |
| 页面 | page_scaffold.dart |
1 |
| 控件 | button.dart, checkbox.dart, switch.dart, slider.dart, picker.dart, segmented_control.dart, date_picker.dart, text_field.dart, search_text_field.dart, activity_indicator.dart, refresh_control.dart |
11 |
| 对话框 | dialog.dart, action_sheet.dart, context_menu.dart |
3 |
| 其他 | dismissible.dart, form_row.dart, section.dart, scrollbar.dart, bouncing_scroll_physics.dart, thumb_painter.dart |
6 |
6.3、本地化系统分析
两个包都依赖相同的本地化基础设施:
dart
// material_ui/lib/src/material_localizations.dart(真实源码)
// 本地化类仍在 material_ui 包中
export 'src/l10n/material_localizations.dart';
export 'src/l10n/material_localizations_en.dart'; // 英语
export 'src/l10n/material_localizations_zh.dart'; // 中文
// ... 其他语言
dart
// cupertino_ui 的入口文件中
export 'src/cupertino_localizations.dart'; // Cupertino 本地化
本地化系统目前只是简单地从 flutter 框架中搬到了独立包中,字符串和翻译文件尚未进行实质性的拆分或重构。
下一篇预告
方案讲完了,下一篇我们来看2026 年 7 月的最新进展:两个包在 pub.dev 上的状态如何?源码目录结构是什么样的?什么时候能用到 1.0.0 正式版?
本文写作于 2026 年 7 月 27 日。所有代码引用均基于 material_ui 0.0.2 和 cupertino_ui 0.0.2 的真实源码。可随时验证。