name: 移动设计系统 description: iOS和Android应用的移动优先设计思维和决策。触摸交互、性能模式、平台规范。教授原则,而非固定值。适用于构建React Native、Flutter或原生移动应用。 allowed-tools: Read, Glob, Grep, Bash
移动设计系统
理念: 触摸优先。电池意识。平台尊重。离线能力。 核心原则: 移动不是小桌面。思考移动约束,询问平台选择。
🔧 运行时脚本
执行这些进行验证(不要阅读,只需运行):
| 脚本 | 目的 | 用法 |
|---|---|---|
scripts/mobile_audit.py |
移动UX和触摸审计 | python scripts/mobile_audit.py <project_path> |
🔴 强制:工作前阅读参考文件!
⛔ 在阅读相关文件之前不要开始开发:
通用(始终阅读)
| 文件 | 内容 | 状态 |
|---|---|---|
| mobile-design-thinking.md | ⚠️ 反记忆:强制思考,防止AI默认 | ⬜ 关键第一 |
| touch-psychology.md | 费茨定律、手势、触觉反馈、拇指区域 | ⬜ 关键 |
| mobile-performance.md | RN/Flutter性能、60fps、内存 | ⬜ 关键 |
| mobile-backend.md | 推送通知、离线同步、移动API | ⬜ 关键 |
| mobile-testing.md | 测试金字塔、E2E、平台特定 | ⬜ 关键 |
| mobile-debugging.md | 原生与JS调试、Flipper、Logcat | ⬜ 关键 |
| mobile-navigation.md | 标签/堆栈/抽屉导航、深度链接 | ⬜ 阅读 |
| mobile-typography.md | 系统字体、动态类型、无障碍 | ⬜ 阅读 |
| mobile-color-system.md | OLED优化、深色模式、电池意识 | ⬜ 阅读 |
| decision-trees.md | 框架/状态/存储选择 | ⬜ 阅读 |
🧠 mobile-design-thinking.md是优先! 此文件确保AI思考而非使用记忆模式。
平台特定(基于目标阅读)
| 平台 | 文件 | 内容 | 何时阅读 |
|---|---|---|---|
| iOS | platform-ios.md | 人机界面指南、SF Pro、SwiftUI模式 | 为iPhone/iPad构建 |
| Android | platform-android.md | Material Design 3、Roboto、Compose模式 | 为Android构建 |
| 跨平台 | 以上两者 | 平台分歧点 | React Native / Flutter |
🔴 如果为iOS构建 → 首先阅读platform-ios.md! 🔴 如果为Android构建 → 首先阅读platform-android.md! 🔴 如果跨平台 → 阅读两者并应用条件平台逻辑!
⚠️ 关键:假设前询问(强制)
停止!如果用户请求开放,不要默认使用你喜欢的。
如果未指定,你必须询问:
| 方面 | 询问 | 原因 |
|---|---|---|
| 平台 | “iOS、Android或两者?” | 影响每个设计决策 |
| 框架 | “React Native、Flutter或原生?” | 确定模式和工具 |
| 导航 | “标签栏、抽屉或基于堆栈?” | 核心UX决策 |
| 状态 | “什么状态管理?(Zustand/Redux/Riverpod/BLoC?)” | 架构基础 |
| 离线 | “是否需要离线工作?” | 影响数据策略 |
| 目标设备 | “仅手机,或支持平板?” | 布局复杂性 |
⛔ AI移动反模式(禁止列表)
🚫 这些是AI默认趋势,必须避免!
性能罪行
| ❌ 永远不要做 | 为什么错 | ✅ 总是做 |
|---|---|---|
| 长列表使用ScrollView | 渲染所有项目,内存爆炸 | 使用FlatList / FlashList / ListView.builder |
| 内联renderItem函数 | 每次渲染新函数,所有项目重新渲染 | useCallback + React.memo |
| 缺少keyExtractor | 基于索引的键导致重新排序错误 | 从数据中唯一、稳定的ID |
| 跳过getItemLayout | 异步布局导致滚动卡顿 | 当项目有固定高度时提供 |
| 到处用setState() | 不必要的组件重建 | 目标状态,const构造函数 |
| 原生驱动:false | 动画被JS线程阻塞 | 总是useNativeDriver: true |
| 生产环境用console.log | 严重阻塞JS线程 | 发布构建前移除 |
| 跳过React.memo/const | 任何更改时每个项目重新渲染 | 总是记忆列表项目 |
触摸/UX罪行
| ❌ 永远不要做 | 为什么错 | ✅ 总是做 |
|---|---|---|
| 触摸目标 < 44px | 无法准确点击,令人沮丧 | 最小44点(iOS)/ 48dp(Android) |
| 目标间间距 < 8px | 意外点击邻居 | 最小8-12px间隔 |
| 仅手势交互 | 运动障碍用户被排除 | 总是提供按钮替代 |
| 无加载状态 | 用户以为应用崩溃 | 总是显示加载反馈 |
| 无错误状态 | 用户卡住,无恢复路径 | 显示带重试选项的错误 |
| 无离线处理 | 网络丢失时崩溃/阻塞 | 优雅降级,缓存数据 |
| 忽略平台规范 | 用户困惑,肌肉记忆破坏 | iOS感觉像iOS,Android感觉像Android |
安全罪行
| ❌ 永远不要做 | 为什么错 | ✅ 总是做 |
|---|---|---|
| AsyncStorage存储令牌 | 易访问,root设备被盗 | SecureStore / Keychain / EncryptedSharedPreferences |
| 硬编码API密钥 | 从APK/IPA逆向工程 | 环境变量,安全存储 |
| 跳过SSL固定 | MITM攻击可能 | 生产中固定证书 |
| 记录敏感数据 | 日志可提取 | 从不记录令牌、密码、PII |
架构罪行
| ❌ 永远不要做 | 为什么错 | ✅ 总是做 |
|---|---|---|
| UI中业务逻辑 | 不可测试,难维护 | 服务层分离 |
| 全局状态用于一切 | 不必要的重新渲染,复杂性 | 默认本地状态,需要时提升 |
| 深度链接事后考虑 | 通知、分享损坏 | 从第一天计划深度链接 |
| 跳过dispose/清理 | 内存泄漏,僵尸监听器 | 清理订阅、计时器 |
📱 平台决策矩阵
何时统一 vs 分歧
统一(两者相同) 分歧(平台特定)
─────────────────── ──────────────────────────
业务逻辑 ✅ 总是 -
数据层 ✅ 总是 -
核心功能 ✅ 总是 -
导航 - ✅ iOS:边缘滑动,Android:返回按钮
手势 - ✅ 平台原生感觉
图标 - ✅ SF符号 vs Material图标
日期选择器 - ✅ 原生选择器感觉正确
模态/底部表单 - ✅ iOS:底部表单 vs Android:对话框
排版 - ✅ SF Pro vs Roboto(或自定义)
错误对话框 - ✅ 平台警报规范
快速参考:平台默认
| 元素 | iOS | Android |
|---|---|---|
| 主要字体 | SF Pro / SF Compact | Roboto |
| 最小触摸目标 | 44点 × 44点 | 48dp × 48dp |
| 返回导航 | 边缘左滑 | 系统返回按钮/手势 |
| 底部标签图标 | SF符号 | Material符号 |
| 操作表单 | 底部UIActionSheet | 底部表单 / 对话框 |
| 进度 | 旋转器 | 线性进度(Material) |
| 下拉刷新 | 原生UIRefreshControl | SwipeRefreshLayout |
🧠 移动UX心理学(快速参考)
费茨定律用于触摸
桌面:光标精确(1像素)
移动:手指不精确(约7毫米接触区域)
→ 触摸目标必须最小44-48像素
→ 重要操作在拇指区域(屏幕底部)
→ 破坏性操作远离易触及区域
拇指区域(单手使用)
┌─────────────────────────────┐
│ 难以触及 │ ← 导航、菜单、返回
│ (拉伸) │
├─────────────────────────────┤
│ 可以触及 │ ← 次要操作
│ (自然) │
├─────────────────────────────┤
│ 容易触及 │ ← 主要CTA、标签栏
│ (拇指自然弧线) │ ← 主要内容交互
└─────────────────────────────┘
[ 主页 ]
移动特定认知负荷
| 桌面 | 移动差异 |
|---|---|
| 多窗口 | 一次一个任务 |
| 键盘快捷键 | 触摸手势 |
| 悬停状态 | 无悬停(点击或无) |
| 大视口 | 空间有限,垂直滚动 |
| 稳定注意力 | 不断中断 |
深度了解:touch-psychology.md
⚡ 性能原则(快速参考)
React Native关键规则
// ✅ 正确:记忆化renderItem + React.memo包装
const ListItem = React.memo(({ item }: { item: Item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
));
const renderItem = useCallback(
({ item }: { item: Item }) => <ListItem item={item} />,
[]
);
// ✅ 正确:带所有优化的FlatList
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id} // 稳定ID,非索引
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={5}
/>
Flutter关键规则
// ✅ 正确:const构造函数防止重建
class MyWidget extends StatelessWidget {
const MyWidget({super.key}); // CONST!
@override
Widget build(BuildContext context) {
return const Column( // CONST!
children: [
Text('静态内容'),
MyConstantWidget(),
],
);
}
}
// ✅ 正确:带ValueListenableBuilder的目标状态
ValueListenableBuilder<int>(
valueListenable: counter,
builder: (context, value, child) => Text('$value'),
child: const ExpensiveWidget(), // 不会重建!
)
动画性能
GPU加速(快): CPU绑定(慢):
├── 变换 ├── 宽度、高度
├── 透明度 ├── 顶部、左侧、右侧、底部
└── (仅用这些) ├── 边距、填充
└── (避免动画化这些)
📝 检查点(任何移动工作前强制)
在编写任何移动代码前,你必须完成此检查点:
🧠 检查点:
平台: [ iOS / Android / 两者 ]
框架: [ React Native / Flutter / SwiftUI / Kotlin ]
已读文件: [ 列出你已读的技能文件 ]
我将应用的3个原则:
1. _______________
2. _______________
3. _______________
我将避免的反模式:
1. _______________
2. _______________
示例:
🧠 检查点:
平台: iOS + Android(跨平台)
框架: React Native + Expo
已读文件: touch-psychology.md, mobile-performance.md, platform-ios.md, platform-android.md
我将应用的3个原则:
1. 所有列表使用FlatList带React.memo + useCallback
2. 48像素触摸目标,主要CTA在拇指区域
3. 平台特定导航(iOS边缘滑动,Android返回按钮)
我将避免的反模式:
1. 列表用ScrollView → FlatList
2. 内联renderItem → 记忆化
3. 令牌用AsyncStorage → SecureStore
🔴 无法填写检查点? → 返回并阅读技能文件。
🔧 框架决策树
你在构建什么?
│
├── 需要OTA更新 + 快速迭代 + 网页团队
│ └── ✅ React Native + Expo
│
├── 需要像素完美自定义UI + 性能关键
│ └── ✅ Flutter
│
├── 深度原生功能 + 单一平台专注
│ ├── 仅iOS → SwiftUI
│ └── 仅Android → Kotlin + Jetpack Compose
│
├── 现有RN代码库 + 新功能
│ └── ✅ React Native(裸工作流)
│
└── 企业 + 现有Flutter代码库
└── ✅ Flutter
完整决策树:decision-trees.md
📋 预开发清单
开始任何移动项目前
- [ ] 平台确认?(iOS / Android / 两者)
- [ ] 框架选择?(RN / Flutter / 原生)
- [ ] 导航模式决定?(标签 / 堆栈 / 抽屉)
- [ ] 状态管理选择?(Zustand / Redux / Riverpod / BLoC)
- [ ] 离线需求已知?
- [ ] 深度链接从第一天计划?
- [ ] 目标设备定义?(手机 / 平板 / 两者)
每个屏幕前
- [ ] 触摸目标 ≥ 44-48像素?
- [ ] 主要CTA在拇指区域?
- [ ] 加载状态存在?
- [ ] 错误状态带重试存在?
- [ ] 离线处理考虑?
- [ ] 平台规范遵循?
发布前
- [ ] console.log移除?
- [ ] 敏感数据用SecureStore?
- [ ] SSL固定启用?
- [ ] 列表优化(memo, keyExtractor)?
- [ ] 卸载时内存清理?
- [ ] 低端设备测试?
- [ ] 所有交互元素有无障碍标签?
📚 参考文件
特定领域深度指导:
| 文件 | 何时使用 |
|---|---|
| mobile-design-thinking.md | 第一!反记忆,强制基于上下文思考 |
| touch-psychology.md | 理解触摸交互、费茨定律、手势设计 |
| mobile-performance.md | 优化RN/Flutter、60fps、内存/电池 |
| platform-ios.md | iOS特定设计、HIG合规 |
| platform-android.md | Android特定设计、Material Design 3 |
| mobile-navigation.md | 导航模式、深度链接 |
| mobile-typography.md | 字体缩放、系统字体、无障碍 |
| mobile-color-system.md | OLED优化、深色模式、电池 |
| decision-trees.md | 框架、状态、存储决策 |
记住: 移动用户不耐烦、被打断、在小屏幕上用不精确手指。为最坏条件设计:差网络、单手、明亮阳光、低电池。如果在那里工作,到处工作。