待办事项四象限拖拽交互设计
概述
四象限待办页面支持待办项在象限内排序以及跨象限拖拽移动,同时保持与后端的数据同步。
交互设计
拖拽状态
| 状态 |
视觉反馈 |
| 按住(未拖拽) |
卡片 scale 1.0,轻微阴影 |
| 拖拽开始 |
卡片 scale 1.03 + 阴影加深,原位置保留半透明占位框 |
| 拖拽中 |
卡片跟随手指(transform),目标象限边框高亮发光 |
| 释放-象限内排序 |
卡片平滑移动到新位置(200ms ease-out) |
| 释放-跨象限移动 |
卡片以 spring 动画弹入目标位置 |
| 操作完成 |
显示成功 Toast |
动画参数
- micro-interaction: 150-300ms
- easing: ease-out 进入,ease-in 退出
- spring: 用于跨象限移动,natural feel
- scale feedback: 0.95-1.05 on press
- exit faster than enter: 退出时长是进入的 60-70%
防误触
- 拖拽启动延迟:100-150ms 确认是长按而非点击
- 仅在按住并移动超过阈值后启动拖拽
数据流
状态管理
API 交互
- 象限内排序:调用
PUT /todos/{id} 更新 priority 和 sort_order
- 跨象限移动:调用
PUT /todos/{id} 更新 priority
乐观更新
- 用户释放后立即更新本地 UI
- 后端请求失败时回滚 + 显示错误 Toast
组件结构
状态定义
| 状态 |
描述 |
idle |
正常显示 |
dragging |
正在拖拽某项 |
dragOverQuadrant |
拖拽到某象限上方 |
reordering |
正在执行排序动画 |
优先级定义
| 象限 |
Priority Value |
| 重要紧急 |
1 |
| 紧急不重要 |
3 |
| 重要不紧急 |
2 |
视觉规范
卡片样式
- 正常:
color: AppColors.todoCardBg, borderRadius: 14px
- 拖拽中:
opacity: 0.5 在原位置显示占位
- 跟随手指:
scale: 1.03, shadow: elevated
象限边框高亮
- 正常:
border: 1px solid {quadrantBorderColor}
- dragOver:
border: 2px solid AppColors.blue400, boxShadow: 0 0 12px AppColors.blue200
插入指示器
- 高度 2px,圆角 1px
- 颜色:
AppColors.blue500
- 位置:两个待办项之间
错误处理
| 场景 |
处理方式 |
| 后端请求失败 |
回滚本地状态,显示错误 Toast |
| 网络断开 |
显示网络错误提示 |
| 并发冲突 |
以最新数据为准,提示用户刷新 |
实现要点
- 使用 Flutter
LongPressDraggable + DragTarget 实现拖拽
- 使用
AnimatedContainer / AnimatedPositioned 实现平滑动画
- 乐观更新:先更新 UI,后请求后端
- 拖拽反馈使用
Transform 而非改变位置,避免 CLS