mcpField
F
flutter-ui

flutter-ui

github.com/naimehossein77设计与 UI447 次安装27 周前更新
代码仓库

关于 flutter-ui

面向 Flutter UI 开发的技能,通过参考文档、设计检查点和审计脚本指导状态管理、导航、主题、布局、动画与性能实践。

主要功能

  1. 01编码前检查相关参考文档
  2. 02按现有导入识别状态管理方式
  3. 03指导 GoRouter 导航与返回逻辑
  4. 04提供主题、布局和动画规则
  5. 05用脚本审计常量与资源释放

适用场景

  1. 01为新屏幕确定状态管理和导航方案
  2. 02检查动画控制器资源释放及重绘边界
  3. 03排查缺少 const 或弃用 API
  4. 04发布前核对主题、布局和错误状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/naimehossein77/claude-flutter-ui-skills --skill flutter-ui

安装后在 Claude Code 中输入/flutter-ui确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

flutter-animations.md
flutter-custom-paint.md
flutter-design-thinking.md
flutter-layout-system.md
flutter-navigation.md
flutter-performance.md
flutter-state-ui.md
flutter-theme-system.md
scripts/
flutter_ui_audit.py

详细介绍

Flutter UI 系统

理念: Flutter 管控每个像素。优先使用 const。由主题驱动。使用 GPU 动画。状态限定作用域。


🔧 运行时脚本

脚本用途用法
scripts/flutter_ui_audit.py审计:检查缺少 const、dispose 泄漏和已弃用的 APIpython scripts/flutter_ui_audit.py <path>

🔴 强制要求:先阅读参考文件

⛔ 阅读相关文件之前不要编写代码:

文件内容优先级
flutter-design-thinking.md防止死记硬背,强制进行上下文分析⬜ 最优先
flutter-state-ui.mdClaude 必须遵循的 Riverpod + Provider 规则⬜ 关键
flutter-navigation.mdGoRouter、PopScope、返回逻辑、深层链接⬜ 关键
flutter-animations.md隐式动画、显式动画、Hero、页面转场、物理效果⬜ 关键
flutter-performance.mdconst、RepaintBoundary、60fps、着色器预热⬜ 关键
flutter-theme-system.mdMaterial 3、ColorScheme、TextTheme、ThemeExtension⬜ 阅读
flutter-layout-system.md响应式布局、LayoutBuilder、MediaQuery、Slivers⬜ 阅读
flutter-custom-paint.mdCanvas、CustomPainter、像素级渲染⬜ 阅读

🧠 先阅读 flutter-design-thinking.md — 防止 AI 套用记忆中的模式。


⚠️ 先询问,不要自行假设

方面询问
状态管理器“使用 Riverpod、Provider、BLoC,还是原生方案?”
导航“使用 GoRouter、auto_route,还是 Navigator 1.0?”
设计系统“使用 Material 3、Cupertino,还是自定义方案?”
平台“仅面向手机,还是要适配平板/桌面?”
Flutter 版本“使用 3.12+ 吗?(PopScope 还是 WillPopScope)”

⛔ 反模式

性能
❌ 绝不使用✅ 始终使用
使用静态子项的 ListView 展示长列表ListView.builder
在动画循环中调用 setStateAnimatedBuilder
使用 Opacity(opacity: 0) 隐藏内容Visibility 或条件渲染
在列表中使用 IntrinsicHeight/IntrinsicWidth固定高度或 SliverFixedExtentList
StatelessWidget 缺少 const始终使用 const MyWidget({super.key})
Column + ListView 未使用 Expanded将 ListView 包在 Expanded 中
在组件中硬编码 Color(0xFF...)Theme.of(context).colorScheme.primary
硬编码 fontSizeTheme.of(context).textTheme.bodyLarge
动画
❌ 绝不使用✅ 始终使用
对 width/height 设置动画对 Transform 设置动画(缩放/平移)
AnimationController 未调用 dispose()在 dispose() 方法中释放
addListener(() => setState((){}))AnimatedBuilder
复杂绘制器缺少 RepaintBoundary将 CustomPaint 包在 RepaintBoundary 中
Hero 标签冲突使用由数据驱动的唯一标签
未设置缓动曲线至少使用 Curves.easeInOut
导航
❌ 绝不使用✅ 始终使用
WillPopScope(Flutter 3.12+ 中已弃用)使用带 canPop + onPopInvokedWithResult 的 PopScope
在 GoRouter 应用中使用 Navigator.pushcontext.go() / context.push()
到处硬编码路由字符串集中定义路由常量
认证页面没有路由守卫GoRouter redirect 回调
根页面上的返回按钮不起作用PopScope(canPop: false) + 退出对话框
状态
❌ 绝不✅ 始终
在 build() 中使用 ref.read()(Riverpod)在 build() 中使用 ref.watch()
在 build() 内定义 Provider顶层 final myProvider = ...
在 build() 中使用 context.read<T>()(Provider)在 build() 中使用 context.watch<T>()
在 ChangeNotifier 中使用 BuildContext传递数据,而非 context
在修改前调用 `notifyListeners()``先修改,再调用 notifyListeners()
使用没有错误处理器的 .when()始终使用 when(data:, loading:, error:)
用 Consumer<T> 包裹整个屏幕在最小的 widget 上使用 Selector<T, R>

🗺️ 导航:go() 与 push() 和 replace()

方法返回栈适用场景
context.go('/path')替换整个栈切换标签页、认证重定向
context.push('/path')添加到栈中逐层深入导航
context.replace('/path')替换当前页面,不可返回认证后从登录页 → 首页
context.pop()移除当前页面返回按钮、关闭模态框
context.pop(result)移除当前页面并返回数据提交表单、选择器结果

🎬 动画选择

WHAT ARE YOU ANIMATING?
├── Simple property change → AnimatedContainer, AnimatedOpacity, TweenAnimationBuilder
├── Complex sequence/stagger → AnimationController + CurvedAnimation + AnimatedBuilder
├── Shared element (cross-screen) → Hero widget + unique tag
├── Page enter/exit → GoRouter CustomTransitionPage or pageBuilder
├── Spring/bounce/momentum → SpringSimulation, BouncingScrollPhysics
└── Vector/sprite → Rive or Lottie package

GPU 安全: transform、opacity → 流畅 受 CPU 限制: width、height、margin、padding → 卡顿


📊 状态管理器自动检测

编写任何状态代码前先扫描导入项:

找到的导入项使用
flutter_riverpodRiverpod 规则
provider 包Provider 规则
两者都没有询问用户 → 新项目推荐 Riverpod

⚡ 性能速查

class MyCard extends StatelessWidget {
  const MyCard({super.key});
  @override
  Widget build(BuildContext context) => const Padding(
    padding: EdgeInsets.all(16),
    child: Text('Hello'),
  );
}

RepaintBoundary(child: AnimatedWidget(...))

ListView.builder(itemCount: n, itemBuilder: (ctx, i) => Item(items[i]))

final name = ref.watch(userProvider.select((u) => u.name));

🧠 检查点(开始任何 Flutter 工作前填写)

🧠 FLUTTER CHECKPOINT:

State:      [ Riverpod / Provider / BLoC / Vanilla ]
Navigation: [ GoRouter / auto_route / Navigator 1.0 ]
Design:     [ Material 3 / Cupertino / Custom ]
Platforms:  [ Mobile / Tablet / Desktop / Web ]
Files Read: [ List files read ]

3 Rules I Will Apply:
1. _______________
2. _______________
3. _______________

Anti-Patterns I Will Avoid:
1. _______________
2. _______________

🔴 无法填写检查点?→ 阅读技能文件。


📋 检查清单

每个屏幕
  • 如果使用 Riverpod,是否使用 ConsumerWidget?是否使用 const 构造函数?
  • 触控目标是否 ≥ 48dp?
  • 是否定义了加载和错误状态?
  • 是否测试了返回导航(PopScope 或 GoRouter canPop)?
  • 是否没有硬编码颜色或字号?
每个动画
  • 是否为 transform/opacity 设置动画,而不是 width/height?
  • 是否调用了 AnimationController.dispose()?
  • 时长是否 ≥ 150ms,且带缓动曲线?
  • 复杂绘制器是否使用了 RepaintBoundary?
发布前
  • 运行审计脚本 — 修复所有 🔴 项
  • flutter analyze — 没有缺少 const 的警告
  • 测试 Android 返回按钮 — 没有卡住的屏幕
  • 测试深色模式 — 所有颜色均来自 Theme
  • 测试平板布局 — 没有溢出
  • 所有 .when() 都处理了错误状态

📚 参考文件

文件适用场景
flutter-design-thinking.md首先阅读 — 防止 AI 默认行为
flutter-state-ui.mdRiverpod 和 Provider 规则、模式、迁移
flutter-navigation.mdGoRouter、返回逻辑、深层链接、标签页
flutter-animations.md隐式、显式、Hero、转场、物理效果
flutter-theme-system.mdMaterial 3、ColorScheme、TextTheme
flutter-layout-system.md响应式、LayoutBuilder、Slivers
flutter-performance.mdconst、RepaintBoundary、DevTools
flutter-custom-paint.mdCanvas、CustomPainter、像素级精准

像素级精准 = 每个间距、颜色和字体选择都有意为之,并由主题驱动。通过设计系统掌控每个像素,而不是依赖魔法数字。

评论

支持 Markdown