mobile-design by claudiodearaujo/izacenter
npx skills add https://github.com/claudiodearaujo/izacenter --skill mobile-design设计理念: 触控优先。电量敏感。尊重平台。支持离线。核心原则: 移动端不是缩小版的桌面端。思考移动端的限制,询问平台选择。
执行以下脚本进行验证(无需阅读,直接运行):
| 脚本 | 用途 | 用法 |
|---|---|---|
scripts/mobile_audit.py | 移动端用户体验与触控审计 | python scripts/mobile_audit.py <project_path> |
⛔ 在阅读相关文件之前,请勿开始开发:
| 文件 | 内容 | 状态 |
|---|
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| mobile-design-thinking.md | ⚠️ 反记忆化:强制思考,防止 AI 使用默认模式 | ⬜ 首要关键 |
| touch-psychology.md | 费茨定律、手势、触觉反馈、拇指热区 | ⬜ 关键 |
| mobile-performance.md | RN/Flutter 性能、60fps、内存 | ⬜ 关键 |
| mobile-backend.md | 推送通知、离线同步、移动端 API | ⬜ 关键 |
| mobile-testing.md | 测试金字塔、端到端测试、平台特定测试 | ⬜ 关键 |
| 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,还是原生开发?" | 决定模式和工具 |
| 导航 | "标签栏、抽屉导航,还是基于堆栈的导航?" | 核心用户体验决策 |
| 状态管理 | "使用什么状态管理方案?(Zustand/Redux/Riverpod/BLoC?)" | 架构基础 |
| 离线 | "是否需要离线工作?" | 影响数据策略 |
| 目标设备 | "仅支持手机,还是也支持平板?" | 布局复杂度 |
🚫 这些是 AI 的默认倾向,必须避免!
| ❌ 切勿做 | 错误原因 | ✅ 始终做 |
|---|---|---|
| 对长列表使用 ScrollView | 渲染所有项目,内存爆炸 | 使用 FlatList / FlashList / ListView.builder |
| 内联 renderItem 函数 | 每次渲染都创建新函数,所有项目重新渲染 | useCallback + React.memo |
| 缺少 keyExtractor | 基于索引的键在重新排序时会导致错误 | 使用数据中唯一、稳定的 ID |
| 跳过 getItemLayout | 异步布局导致滚动卡顿 | 当项目高度固定时提供 |
| 到处使用 setState() | 不必要的组件重建 | 有针对性的状态,使用 const 构造函数 |
| Native driver: false | 动画被 JS 线程阻塞 | 始终使用 useNativeDriver: true |
| 生产环境使用 console.log | 严重阻塞 JS 线程 | 发布构建前移除 |
| 跳过 React.memo/const | 任何变化都会导致所有项目重新渲染 | 始终对列表项进行记忆化 |
| ❌ 切勿做 | 错误原因 | ✅ 始终做 |
|---|---|---|
| 触控目标 < 44px | 无法准确点击,令人沮丧 | 最小 44pt (iOS) / 48dp (Android) |
| 目标间距 < 8px | 容易误触相邻目标 | 最小 8-12px 间距 |
| 仅手势交互 | 排除行动不便的用户 | 始终提供按钮替代方案 |
| 无加载状态 | 用户以为应用崩溃 | 始终显示加载反馈 |
| 无错误状态 | 用户卡住,无法恢复 | 显示错误并提供重试选项 |
| 无离线处理 | 网络丢失时崩溃/阻塞 | 优雅降级,使用缓存数据 |
| 忽略平台惯例 | 用户困惑,肌肉记忆被破坏 | iOS 感觉像 iOS,Android 感觉像 Android |
| ❌ 切勿做 | 错误原因 | ✅ 始终做 |
|---|---|---|
| 将令牌存储在 AsyncStorage | 易于访问,在已 root 设备上会被窃取 | 使用 SecureStore / Keychain / EncryptedSharedPreferences |
| 硬编码 API 密钥 | 可从 APK/IPA 逆向工程获取 | 使用环境变量,安全存储 |
| 跳过 SSL 证书锁定 | 可能遭受中间人攻击 | 在生产环境中锁定证书 |
| 记录敏感数据 | 日志可能被提取 | 切勿记录令牌、密码、个人身份信息 |
| ❌ 切勿做 | 错误原因 | ✅ 始终做 |
|---|---|---|
| 业务逻辑写在 UI 中 | 不可测试,难以维护 | 服务层分离 |
| 所有东西都用全局状态 | 不必要的重新渲染,复杂度高 | 默认使用局部状态,需要时提升 |
| 深度链接作为事后考虑 | 通知、分享功能失效 | 从第一天起就规划深度链接 |
| 跳过 dispose/cleanup | 内存泄漏,僵尸监听器 | 清理订阅、定时器 |
统一(两者相同) 区分(平台特定)
─────────────────── ──────────────────────────
业务逻辑 ✅ 始终 -
数据层 ✅ 始终 -
核心功能 ✅ 始终 -
导航 - ✅ iOS:边缘滑动,Android:返回按钮
手势 - ✅ 平台原生感觉
图标 - ✅ SF Symbols vs Material Icons
日期选择器 - ✅ 原生选择器感觉更自然
模态框/底部动作面板 - ✅ iOS:底部动作面板 vs Android:对话框
排版 - ✅ SF Pro vs Roboto(或自定义)
错误对话框 - ✅ 遵循平台惯例的警告框
| 元素 | iOS | Android |
|---|---|---|
| 主要字体 | SF Pro / SF Compact | Roboto |
| 最小触控目标 | 44pt × 44pt | 48dp × 48dp |
| 返回导航 | 左侧边缘滑动 | 系统返回按钮/手势 |
| 底部标签栏图标 | SF Symbols | Material Symbols |
| 动作面板 | 从底部弹出的 UIActionSheet | Bottom Sheet / Dialog |
| 进度指示器 | 旋转器 | 线性进度条 (Material) |
| 下拉刷新 | 原生 UIRefreshControl | SwipeRefreshLayout |
桌面端:光标精确(1px)
移动端:手指不精确(约 7mm 接触面积)
→ 触控目标必须至少 44-48px
→ 重要操作放在拇指热区(屏幕底部)
→ 破坏性操作远离易触及区域
┌─────────────────────────────┐
│ 难以触及区域 │ ← 导航、菜单、返回
│ (需伸展) │
├─────────────────────────────┤
│ 可触及区域 │ ← 次要操作
│ (自然) │
├─────────────────────────────┤
│ 易触及区域 │ ← 主要操作按钮、标签栏
│ (拇指自然弧度区) │ ← 主要内容交互
└─────────────────────────────┘
[ 主页 ]
| 桌面端 | 移动端差异 |
|---|---|
| 多窗口 | 一次一个任务 |
| 键盘快捷键 | 触摸手势 |
| 悬停状态 | 无悬停(点击或无) |
| 大视口 | 空间有限,垂直滚动 |
| 注意力稳定 | 经常被打断 |
深入了解:touch-psychology.md
// ✅ 正确:记忆化的 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}
/>
// ✅ 正确:const 构造函数防止重建
class MyWidget extends StatelessWidget {
const MyWidget({super.key}); // 常量!
@override
Widget build(BuildContext context) {
return const Column( // 常量!
children: [
Text('静态内容'),
MyConstantWidget(),
],
);
}
}
// ✅ 正确:使用 ValueListenableBuilder 进行有目标的状态管理
ValueListenableBuilder<int>(
valueListenable: counter,
builder: (context, value, child) => Text('$value'),
child: const ExpensiveWidget(), // 不会重建!
)
GPU 加速(快): CPU 密集型(慢):
├── transform ├── width, height
├── opacity ├── top, left, right, bottom
└── (仅使用这些) ├── margin, padding
└── (避免动画化这些属性)
在编写任何移动端代码之前,你必须完成此检查点:
🧠 检查点:
平台: [ 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. 48px 触控目标,主要操作按钮放在拇指热区
3. 平台特定导航(iOS 边缘滑动,Android 返回按钮)
我将避免的反模式:
1. 对列表使用 ScrollView → 改用 FlatList
2. 内联 renderItem → 记忆化
3. 使用 AsyncStorage 存储令牌 → 改用 SecureStore
🔴 无法填写检查点? → 返回并阅读技能文件。
你要构建什么?
│
├── 需要 OTA 更新 + 快速迭代 + 有 Web 团队
│ └── ✅ React Native + Expo
│
├── 需要像素级完美自定义 UI + 性能关键
│ └── ✅ Flutter
│
├── 深度原生功能 + 单一平台专注
│ ├── 仅 iOS → SwiftUI
│ └── 仅 Android → Kotlin + Jetpack Compose
│
├── 现有 RN 代码库 + 新功能
│ └── ✅ React Native (bare workflow)
│
└── 企业级 + 现有 Flutter 代码库
└── ✅ Flutter
完整决策树:decision-trees.md
特定领域的深入指导:
| 文件 | 何时使用 |
|---|---|
| mobile-design-thinking.md | 首要!反记忆化,强制基于上下文思考 |
| touch-psychology.md | 理解触控交互、费茨定律、手势设计 |
| mobile-performance.md | 优化 RN/Flutter、60fps、内存/电量 |
| platform-ios.md | iOS 特定设计、遵循人机界面指南 |
| platform-android.md | Android 特定设计、Material Design 3 |
| mobile-navigation.md | 导航模式、深度链接 |
| mobile-typography.md | 字体比例、系统字体、无障碍访问 |
| mobile-color-system.md | OLED 优化、深色模式、电量 |
| decision-trees.md | 框架、状态、存储决策 |
记住: 移动用户缺乏耐心、容易被打断,并且在小屏幕上使用不精确的手指操作。为最差条件设计:网络差、单手操作、阳光强烈、电量低。如果在这种情况下能工作,那么在任何地方都能工作。
每周安装数
1
仓库
GitHub Stars
1
首次出现
1 天前
安全审计
安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
Philosophy: Touch-first. Battery-conscious. Platform-respectful. Offline-capable. Core Principle: Mobile is NOT a small desktop. THINK mobile constraints, ASK platform choice.
Execute these for validation (don't read, just run):
| Script | Purpose | Usage |
|---|---|---|
scripts/mobile_audit.py | Mobile UX & Touch Audit | python scripts/mobile_audit.py <project_path> |
⛔ DO NOT start development until you read the relevant files:
| File | Content | Status |
|---|---|---|
| mobile-design-thinking.md | ⚠️ ANTI-MEMORIZATION: Forces thinking, prevents AI defaults | ⬜ CRITICAL FIRST |
| touch-psychology.md | Fitts' Law, gestures, haptics, thumb zone | ⬜ CRITICAL |
| mobile-performance.md | RN/Flutter performance, 60fps, memory | ⬜ CRITICAL |
| mobile-backend.md | Push notifications, offline sync, mobile API | ⬜ CRITICAL |
| mobile-testing.md |
🧠 mobile-design-thinking.md is PRIORITY! This file ensures AI thinks instead of using memorized patterns.
| Platform | File | Content | When to Read |
|---|---|---|---|
| iOS | platform-ios.md | Human Interface Guidelines, SF Pro, SwiftUI patterns | Building for iPhone/iPad |
| Android | platform-android.md | Material Design 3, Roboto, Compose patterns | Building for Android |
| Cross-Platform | Both above | Platform divergence points | React Native / Flutter |
🔴 If building for iOS → Read platform-ios.md FIRST! 🔴 If building for Android → Read platform-android.md FIRST! 🔴 If cross-platform → Read BOTH and apply conditional platform logic!
STOP! If the user's request is open-ended, DO NOT default to your favorites.
| Aspect | Ask | Why |
|---|---|---|
| Platform | "iOS, Android, or both?" | Affects EVERY design decision |
| Framework | "React Native, Flutter, or native?" | Determines patterns and tools |
| Navigation | "Tab bar, drawer, or stack-based?" | Core UX decision |
| State | "What state management? (Zustand/Redux/Riverpod/BLoC?)" | Architecture foundation |
| Offline | "Does this need to work offline?" | Affects data strategy |
| Target devices | "Phone only, or tablet support?" | Layout complexity |
🚫 These are AI default tendencies that MUST be avoided!
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|---|---|---|
| ScrollView for long lists | Renders ALL items, memory explodes | Use FlatList / FlashList / ListView.builder |
| Inline renderItem function | New function every render, all items re-render | useCallback + React.memo |
| Missing keyExtractor | Index-based keys cause bugs on reorder | Unique, stable ID from data |
| Skip getItemLayout |
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|---|---|---|
| Touch target < 44px | Impossible to tap accurately, frustrating | Minimum 44pt (iOS) / 48dp (Android) |
| Spacing < 8px between targets | Accidental taps on neighbors | Minimum 8-12px gap |
| Gesture-only interactions | Motor impaired users excluded | Always provide button alternative |
| No loading state | User thinks app crashed | ALWAYS show loading feedback |
| No error state | User stuck, no recovery path | Show error with retry option |
| No offline handling | Crash/block when network lost | Graceful degradation, cached data |
| Ignore platform conventions | Users confused, muscle memory broken | iOS feels iOS, Android feels Android |
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|---|---|---|
| Token in AsyncStorage | Easily accessible, stolen on rooted device | SecureStore / Keychain / EncryptedSharedPreferences |
| Hardcode API keys | Reverse engineered from APK/IPA | Environment variables, secure storage |
| Skip SSL pinning | MITM attacks possible | Pin certificates in production |
| Log sensitive data | Logs can be extracted | Never log tokens, passwords, PII |
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|---|---|---|
| Business logic in UI | Untestable, unmaintainable | Service layer separation |
| Global state for everything | Unnecessary re-renders, complexity | Local state default, lift when needed |
| Deep linking as afterthought | Notifications, shares broken | Plan deep links from day one |
| Skip dispose/cleanup | Memory leaks, zombie listeners | Clean up subscriptions, timers |
UNIFY (same on both) DIVERGE (platform-specific)
─────────────────── ──────────────────────────
Business Logic ✅ Always -
Data Layer ✅ Always -
Core Features ✅ Always -
Navigation - ✅ iOS: edge swipe, Android: back button
Gestures - ✅ Platform-native feel
Icons - ✅ SF Symbols vs Material Icons
Date Pickers - ✅ Native pickers feel right
Modals/Sheets - ✅ iOS: bottom sheet vs Android: dialog
Typography - ✅ SF Pro vs Roboto (or custom)
Error Dialogs - ✅ Platform conventions for alerts
| Element | iOS | Android |
|---|---|---|
| Primary Font | SF Pro / SF Compact | Roboto |
| Min Touch Target | 44pt × 44pt | 48dp × 48dp |
| Back Navigation | Edge swipe left | System back button/gesture |
| Bottom Tab Icons | SF Symbols | Material Symbols |
| Action Sheet | UIActionSheet from bottom | Bottom Sheet / Dialog |
| Progress | Spinner | Linear progress (Material) |
| Pull to Refresh | Native UIRefreshControl | SwipeRefreshLayout |
Desktop: Cursor is precise (1px)
Mobile: Finger is imprecise (~7mm contact area)
→ Touch targets MUST be 44-48px minimum
→ Important actions in THUMB ZONE (bottom of screen)
→ Destructive actions AWAY from easy reach
┌─────────────────────────────┐
│ HARD TO REACH │ ← Navigation, menu, back
│ (stretch) │
├─────────────────────────────┤
│ OK TO REACH │ ← Secondary actions
│ (natural) │
├─────────────────────────────┤
│ EASY TO REACH │ ← PRIMARY CTAs, tab bar
│ (thumb's natural arc) │ ← Main content interaction
└─────────────────────────────┘
[ HOME ]
| Desktop | Mobile Difference |
|---|---|
| Multiple windows | ONE task at a time |
| Keyboard shortcuts | Touch gestures |
| Hover states | NO hover (tap or nothing) |
| Large viewport | Limited space, scroll vertical |
| Stable attention | Interrupted constantly |
For deep dive: touch-psychology.md
// ✅ CORRECT: Memoized renderItem + React.memo wrapper
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} />,
[]
);
// ✅ CORRECT: FlatList with all optimizations
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id} // Stable ID, NOT index
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={5}
/>
// ✅ CORRECT: const constructors prevent rebuilds
class MyWidget extends StatelessWidget {
const MyWidget({super.key}); // CONST!
@override
Widget build(BuildContext context) {
return const Column( // CONST!
children: [
Text('Static content'),
MyConstantWidget(),
],
);
}
}
// ✅ CORRECT: Targeted state with ValueListenableBuilder
ValueListenableBuilder<int>(
valueListenable: counter,
builder: (context, value, child) => Text('$value'),
child: const ExpensiveWidget(), // Won't rebuild!
)
GPU-accelerated (FAST): CPU-bound (SLOW):
├── transform ├── width, height
├── opacity ├── top, left, right, bottom
└── (use these ONLY) ├── margin, padding
└── (AVOID animating these)
For complete guide: mobile-performance.md
Before writing ANY mobile code, you MUST complete this checkpoint:
🧠 CHECKPOINT:
Platform: [ iOS / Android / Both ]
Framework: [ React Native / Flutter / SwiftUI / Kotlin ]
Files Read: [ List the skill files you've read ]
3 Principles I Will Apply:
1. _______________
2. _______________
3. _______________
Anti-Patterns I Will Avoid:
1. _______________
2. _______________
Example:
🧠 CHECKPOINT:
Platform: iOS + Android (Cross-platform)
Framework: React Native + Expo
Files Read: touch-psychology.md, mobile-performance.md, platform-ios.md, platform-android.md
3 Principles I Will Apply:
1. FlatList with React.memo + useCallback for all lists
2. 48px touch targets, thumb zone for primary CTAs
3. Platform-specific navigation (edge swipe iOS, back button Android)
Anti-Patterns I Will Avoid:
1. ScrollView for lists → FlatList
2. Inline renderItem → Memoized
3. AsyncStorage for tokens → SecureStore
🔴 Can't fill the checkpoint? → GO BACK AND READ THE SKILL FILES.
WHAT ARE YOU BUILDING?
│
├── Need OTA updates + rapid iteration + web team
│ └── ✅ React Native + Expo
│
├── Need pixel-perfect custom UI + performance critical
│ └── ✅ Flutter
│
├── Deep native features + single platform focus
│ ├── iOS only → SwiftUI
│ └── Android only → Kotlin + Jetpack Compose
│
├── Existing RN codebase + new features
│ └── ✅ React Native (bare workflow)
│
└── Enterprise + existing Flutter codebase
└── ✅ Flutter
For complete decision trees: decision-trees.md
For deeper guidance on specific areas:
| File | When to Use |
|---|---|
| mobile-design-thinking.md | FIRST! Anti-memorization, forces context-based thinking |
| touch-psychology.md | Understanding touch interaction, Fitts' Law, gesture design |
| mobile-performance.md | Optimizing RN/Flutter, 60fps, memory/battery |
| platform-ios.md | iOS-specific design, HIG compliance |
| platform-android.md | Android-specific design, Material Design 3 |
| mobile-navigation.md | Navigation patterns, deep linking |
| mobile-typography.md |
Remember: Mobile users are impatient, interrupted, and using imprecise fingers on small screens. Design for the WORST conditions: bad network, one hand, bright sun, low battery. If it works there, it works everywhere.
Weekly Installs
1
Repository
GitHub Stars
1
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketFailSnykPass
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
109,600 周安装
| Testing pyramid, E2E, platform-specific |
| ⬜ CRITICAL |
| mobile-debugging.md | Native vs JS debugging, Flipper, Logcat | ⬜ CRITICAL |
| mobile-navigation.md | Tab/Stack/Drawer, deep linking | ⬜ Read |
| mobile-typography.md | System fonts, Dynamic Type, a11y | ⬜ Read |
| mobile-color-system.md | OLED, dark mode, battery-aware | ⬜ Read |
| decision-trees.md | Framework/state/storage selection | ⬜ Read |
| Async layout = janky scroll |
| Provide when items have fixed height |
| setState() everywhere | Unnecessary widget rebuilds | Targeted state, const constructors |
| Native driver: false | Animations blocked by JS thread | useNativeDriver: true always |
| console.log in production | Blocks JS thread severely | Remove before release build |
| Skip React.memo/const | Every item re-renders on any change | Memoize list items ALWAYS |
| Type scale, system fonts, accessibility |
| mobile-color-system.md | OLED optimization, dark mode, battery |
| decision-trees.md | Framework, state, storage decisions |