48 lines
2.4 KiB
Markdown
48 lines
2.4 KiB
Markdown
# K87 下拉刷新完成后回弹实施计划
|
|
|
|
## 目标
|
|
|
|
将全局 `AppPullToRefresh` 改为刷新完成前保持下拉高度:松手达到阈值后内容停在 56px,显示“正在刷新”,`onRefresh` 完成后再用 200ms easeOut 回弹到 0。
|
|
|
|
## 根因
|
|
|
|
- 当前下拉位移主要由 `BouncingScrollPhysics` 的系统 overscroll 提供。
|
|
- 松手后滚动位置立即执行系统回弹,组件只保留一个小指示器。
|
|
- 刷新期间没有独立的内容保持位移,因此无法维持下拉状态。
|
|
|
|
## 范围
|
|
|
|
- ReelShort `lib/core/widgets/app_pull_to_refresh.dart`
|
|
- ReelShort `test/core/app_pull_to_refresh_test.dart`
|
|
- FruitServer `docs/plans/PROGRESS.md`
|
|
|
|
## 实现计划
|
|
|
|
1. 将 `AppPullToRefresh.physics` 从 Bouncing 改为 Clamping,阻止系统 overscroll 自行产生内容位移。
|
|
2. 使用 `AnimationController` 和 `Transform.translate` 统一控制内容位移;pull/armed 使用当前拖动距离,refreshing 固定 56,完成后回 0。
|
|
3. 松手达到阈值后,200ms easeOut 将当前距离过渡到 56;刷新期间忽略滚动通知并通过 `IgnorePointer` 阻止重复下拉。
|
|
4. `onRefresh` 完成后以 200ms easeOut 回到 0;指示器透明度跟随位移回弹淡出,结束后状态为 idle。
|
|
5. 检查全部 11 个使用方均传入 `AppPullToRefresh.physics`,保证全局组件行为一致。
|
|
|
|
## 测试计划
|
|
|
|
- 使用挂起的 `Completer` 模拟刷新未完成。
|
|
- 松手瞬间断言内容仍高于 hold,200ms 后稳定为 56,再等待 300ms 仍保持 56。
|
|
- 断言刷新状态显示 `CircularProgressIndicator` 与 `Refreshing…`。
|
|
- 刷新中再次下拉,断言 `onRefresh` 调用数仍为 1、offset 仍为 56。
|
|
- 完成 `Completer` 后断言 offset 回到 0、刷新指示器消失。
|
|
|
|
## 风险与处理
|
|
|
|
- 改为 Clamping 后不再依赖平台 overscroll 提供下拉视觉;内容位移完全由组件控制,避免双倍移动。
|
|
- 刷新期间阻止列表交互,避免用户手势破坏保持高度。
|
|
- 组件卸载时动画控制器会取消动画;异步刷新完成后仅在 mounted 时执行回弹收尾。
|
|
|
|
## Git
|
|
|
|
- ReelShort 从 `develop` 创建 `feat/pull-to-refresh-hold`。
|
|
- 提交:`feat(ui): 下拉刷新完成后才回弹`。
|
|
- 作者:`Zhou Weidong <502333560@qq.com>`。
|
|
- `--no-ff` 合回 `develop` 并 push,不使用 force push,不执行 `git add -A`。
|
|
- FruitServer 追加 PROGRESS 留痕;不安装真机,完成后等待用户验收。
|