Files
social-app/docs/superpowers/specs/2026-03-20-todo-quadrant-drag-design.md
T

3.1 KiB
Raw Blame History

待办事项四象限拖拽交互设计

概述

四象限待办页面支持待办项在象限内排序以及跨象限拖拽移动,同时保持与后端的数据同步。

交互设计

拖拽状态

状态 视觉反馈
按住(未拖拽) 卡片 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 确认是长按而非点击
  • 仅在按住并移动超过阈值后启动拖拽

数据流

状态管理

_QuadrantScreenState
  ├── List<TodoResponse> _todos
  ├── DragState _dragState (null / dragging)
  └── int? _dragTargetQuadrant (1, 2, 3)

API 交互

  1. 象限内排序:调用 PUT /todos/{id} 更新 prioritysort_order
  2. 跨象限移动:调用 PUT /todos/{id} 更新 priority

乐观更新

  • 用户释放后立即更新本地 UI
  • 后端请求失败时回滚 + 显示错误 Toast

组件结构

TodoQuadrantsScreen
├── _QuadrantDragContainer (LongPressDraggable + DragTarget)
│   ├── _QuadrantCard (象限容器)
│   └── _TodoDragItem (可拖拽待办项)
└── _DragFeedbackWidget (拖拽中的视觉反馈)

状态定义

状态 描述
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
网络断开 显示网络错误提示
并发冲突 以最新数据为准,提示用户刷新

实现要点

  1. 使用 Flutter LongPressDraggable + DragTarget 实现拖拽
  2. 使用 AnimatedContainer / AnimatedPositioned 实现平滑动画
  3. 乐观更新:先更新 UI,后请求后端
  4. 拖拽反馈使用 Transform 而非改变位置,避免 CLS