关于 flutter-ui
flutter-ui 是指导 Flutter 界面实现的技能,面向构建适配不同屏幕尺寸的应用界面。内容涵盖性能、设计令牌、组件结构、布局适配和无障碍状态处理。
主要功能
- 01优先使用 const 并优化列表渲染
- 02通过设计令牌统一样式
- 03将可复用界面拆分为组件
- 04采用 Slivers 和适配式布局
- 05处理加载、错误及空状态
- 06支持键盘操作与无障碍语义
适用场景
- 01构建适配手机、平板和桌面的界面
- 02优化包含大量条目的滚动列表
- 03统一应用颜色、间距和排版
- 04检查界面的无障碍与交互状态
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-ui安装后在 Claude Code 中输入/flutter-ui确认已加载。
详细介绍
1. 性能与渲染
- Const 优先:任何可以使用
const的组件都必须使用const。 - 延迟渲染:对于超过 10 个条目的列表,使用
SliverList.builder或SliverGrid.builder。 - 重绘边界:将复杂动画封装在
RepaintBoundary中。 - Impeller 渲染:Impeller 是 iOS 和 Android 的默认渲染引擎。确保自定义画布绘制经过优化,且不依赖 Skia 特有的行为。
- 隔离区解析:对于超过 1 MB 的 JSON,使用
compute()或Isolate。 - BuildContext 安全性:在异步间隙中使用
context前,检查mounted。
2. 设计令牌(主题)
使用 AppColors、AppSpacing、AppRadius 和 AppTypography。绝不硬编码原始值。
- 颜色:使用
context.colorScheme.primary或AppColors。支持浅色和深色模式。 - 间距:使用
AppSpacing.sm(8)、AppSpacing.md(16)等。使用SizedBox设置间隔。 - 圆角:使用
AppRadius.md(12)以保持圆角一致。 - 排版:使用
context.textTheme.bodyMedium。支持文本缩放。
3. 可复用组件
- 单一职责:每个组件都应有一个明确的用途。
- 参数化:提供可用于自定义的参数。
- 复杂度:将多次使用的组件或代码块提取到
core/views/widgets中。 - 键:为交互式组件分配
Key('feature_action_id'),以便测试访问。
4. 组件与交互模式
- 提取:严格禁止使用私有
_build*()方法。应提取为单独的组件类。 - Slivers:对于非简单的可滚动布局,优先使用带 Slivers 的
CustomScrollView。 - FAB:主要的正向操作(添加、创建)使用悬浮操作按钮。
- 滚动内边距:存在 FAB 或 BottomBar 时,添加动态底部内边距以防止内容重叠。
- 返回处理:绝不使用已弃用的
WillPopScope组件。使用标准的PopScope组件拦截或阻止返回导航。 - 底部表单与屏幕:复杂表单优先使用完整的
Scaffold屏幕,而不是ModalBottomSheet。
5. 自适应与响应式设计及常见修复
- 移动端优先:先针对移动端设计,再适配平板(
600-840dp)和桌面端(>840dp)。使用MediaQuery.sizeOf(context).width。 - 布局构建器:当组件渲染取决于其直接父级的约束,而非整个屏幕时,使用
LayoutBuilder。 - 安全区域与 Android 15:使用
SafeArea包裹主要布局,避免设备刘海和系统栏遮挡。由于 Android 15 默认强制采用边缘到边缘渲染,请使用MediaQuery.paddingOf(context)或SafeArea,防止组件被系统状态栏或导航栏遮挡。 - 模块化 UI 导入:Flutter 3.44+ 将
material和cupertino与核心框架解耦。在纯结构组件中,仅导入package:flutter/widgets.dart,以保持清晰的库分离。 - 溢出修复:
A RenderFlex overflowed...:通常表示组件所需空间超出Row或Column中的可用空间。将出问题的组件包裹在Expanded或Flexible中。Vertical viewport was given unbounded height:通常发生在嵌套可滚动视图时(例如在Column中放置ListView)。对ListView使用Expanded,或设置shrinkWrap: true。
- 规则:除非某个独特功能有严格要求,否则绝不锁定屏幕方向。支持桌面用户使用键盘导航和悬停效果。
6. 响应式布局模式
LayoutBuilder 与 MediaQuery 的比较
| 工具 | 使用场景 | 返回值 |
|---|---|---|
MediaQuery.sizeOf(context) | 布局取决于屏幕尺寸(应用级断点) | 屏幕的 Size |
LayoutBuilder | 布局取决于父级约束(组件级) | 来自父级的 BoxConstraints |
规则:页面级布局使用 MediaQuery。可根据容器调整布局的可复用组件使用 LayoutBuilder。
断点约定
| 窗口类别 | 宽度 | 布局 | 列数 |
|---|---|---|---|
| 紧凑 | < 600dp | 单列,底部导航 | 4 |
| 中等 | 600-840dp | 双面板,导航栏 | 8 |
| 展开 | > 840dp | 多面板,侧边导航 | 12 |
自适应布局模式
Widget build(BuildContext context) {
final width = MediaQuery.sizeOf(context).width;
return switch (width) {
< 600 => const MobileLayout(),
< 840 => const TabletLayout(),
_ => const DesktopLayout(),
};
}
约束类 Widget
| Widget | 行为 | 使用场景 |
|---|---|---|
Expanded | 填充 Row/Column 中所有剩余空间 | 子项应拉伸 |
Flexible | 允许子项小于剩余空间 | 子项有自然尺寸 |
FractionallySizedBox | 按父项的比例设置尺寸(例如,0.5 = 50%) | 按比例布局 |
ConstrainedBox | 设置最小/最大约束 | 有界灵活布局 |
SizedBox | 固定绝对尺寸 | 已知确切尺寸 |
7. UI 状态与无障碍
- 状态:始终处理加载、错误和空状态,并提供清晰的提示。
- 无障碍:添加
Semantics标签。确保触控目标为 48x48 dp。符合 WCAG AA 对比度标准。
评论
支持 Markdown