commit 36220620a33af4fb22fcd5e2a0c82206ff5079a3 Author: xiaji Date: Tue May 19 22:44:04 2026 +0800 docs: 添加 Android 标尺应用设计文档 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d573573 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.iml +.gradle/ +build/ +.idea/ +local.properties +captures/ +.externalNativeBuild/ +.cxx/ +*.apk +*.aab +*.ap_ +.superpowers/ diff --git a/docs/superpowers/specs/2026-05-19-android-ruler-design.md b/docs/superpowers/specs/2026-05-19-android-ruler-design.md new file mode 100644 index 0000000..3590a48 --- /dev/null +++ b/docs/superpowers/specs/2026-05-19-android-ruler-design.md @@ -0,0 +1,157 @@ +# Android 标尺测量应用 - 设计文档 + +## 概述 + +一款利用手机屏幕作为物理标尺的测量工具应用。支持屏幕标尺测量和拍照标注两种模式,通过屏幕 DPI + 手动校准保证测量精度。 + +**技术栈**:Kotlin + Jetpack Compose + Material 3 +**最低 API**:24 (Android 7.0) +**主要依赖**:CameraX、DataStore Preferences + +--- + +## 架构 + +### 顶层导航 + +``` +┌──────────────────────────────────────────┐ +│ 🔧 设置(AppBar 右上角图标) │ +├──────────────────────────────────────────┤ +│ │ +│ 标尺测量模式 / 拍照标注模式 │ +│ │ +├──────────────────────────────────────────┤ +│ 📏 标尺 | 📷 拍照(底部导航栏) │ +└──────────────────────────────────────────┘ +``` + +底部导航栏切换两种模式。右上角齿轮图标进入设置页面。设置页面使用独立 Screen 展示。 + +### 模式一:标尺测量 + +屏幕显示物理标尺。竖屏时纵向绘制,横屏时横向绘制。支持滚动查看完整量程。 + +**绘制规则**: +- 三级刻度:cm 线(最长,标注数字)、0.5cm 线(中等)、mm 线(最短) +- 测量标记:用户点击放置起点(绿色)、终点(红色),可拖拽微调 +- 结果展示:两点间距精确到 0.5mm + +**关键计算**: +``` +pixelPerCm = (dpi / 2.54) × cmCorrectionFactor +totalCm = screenSide / pixelPerCm +``` + +### 模式二:拍照标注 + +``` +拍照 → 预览确认 → 编辑标注 → 合成保存 +``` + +- **拍照**:CameraX 实现相机预览和拍照 +- **标注编辑**:在照片上叠加一个虚拟小标尺图 + - 小标尺是主标尺的缩略版(指定长度如 2/3/5/10cm),样式一致 + - 手势:单指拖拽移动、双指旋转 + 缩放 + - 底部切换标尺长度 + +- **合成保存**:照片 Bitmap + 标尺 Canvas 绘制合并为一张图,通过 MediaStore 保存到相册 + +### 设置页面 + +| 设置项 | 类型 | 说明 | +|--------|------|------| +| 标尺校准 | 交互页面 | 拖拽滑块对齐真实尺子的 10cm,保存修正系数 | +| 默认方向 | 选择 | 竖屏 / 横屏 / 自适应 | +| 拍照标尺默认长度 | 选择 | 2cm / 5cm / 10cm | +| 关于 | 信息 | 版本号等 | + +--- + +## 状态管理 + +### 单一 ViewModel + +```kotlin +data class RulerUiState( + val orientation: Orientation, + val pixelPerCm: Float, + val scrollOffset: Float, + val markStartCm: Float?, + val markEndCm: Float?, + val currentMode: Mode, // RULER / PHOTO + val photoBitmap: Bitmap?, + val overlayRulerLength: Float, + val overlayPosition: Offset, + val overlayScale: Float, + val overlayRotation: Float, + val showSettings: Boolean, + val cmCorrectionFactor: Float, +) +``` + +### DataStore 持久化 + +| Key | 类型 | 默认值 | +|-----|------|--------| +| `cm_correction_factor` | Float | 1.0 | +| `is_calibrated` | Boolean | false | +| `default_orientation` | String | "auto" | +| `default_ruler_length` | Float | 3.0 | + +统一封装为 `SettingsRepository`。 + +--- + +## 项目结构 + +``` +app/src/main/java/com/example/androidruler/ +├── MainActivity.kt +├── RulerApplication.kt +├── ui/ +│ ├── RulerScreen.kt +│ ├── RulerCanvas.kt +│ ├── Markers.kt +│ ├── ControlBar.kt +│ ├── photo/ +│ │ ├── PhotoMarkScreen.kt +│ │ ├── CameraCapture.kt +│ │ ├── PhotoEditor.kt +│ │ └── RulerOverlay.kt +│ ├── settings/ +│ │ ├── SettingsScreen.kt +│ │ └── CalibrationScreen.kt +│ └── util/ +│ └── ImageSaver.kt +├── viewmodel/ +│ └── RulerViewModel.kt +├── data/ +│ └── SettingsRepository.kt +└── theme/ + └── Theme.kt +``` + +--- + +## AndroidManifest 权限 + +```xml + + +``` + +--- + +## 边界情况 + +| 场景 | 处理 | +|------|------| +| DPI 返回异常(如 160) | 弹窗提示手动校准 | +| 首次启动无校准数据 | 用自动 DPI 先行绘制,顶部显示校准提示条 | +| 屏幕旋转 | 标记点位置按比例换算保留 | +| 标记点极短距离(<1mm) | 显示 "< 1mm" | +| 拍照权限拒绝 | 提示引导去设置页开启 | +| 相机不可用 | 模拟器/无相机设备降级为纯标尺模式 | +| 图片保存失败 | Toast 提示重试 |