docs(plans): 记录 K87.1 下拉刷新冻结位移

This commit is contained in:
Zhou Weidong committed 2026-10-21 15:26:15 +08:00
1 parent 7ab6dc62dd
commit edd279372d
2 files changed
+69

No files matched your search

@@ -0,0 +1,46 @@
# K87.1 下拉刷新冻结位移实施计划
## 目标
修复刷新 pending 期间仍从松手距离回收到 56px 的视觉回弹。达到阈值后冻结当前下拉距离 D,刷新完成前 offset 不变化,完成后才用 200ms easeOut 回到 0。
## 根因
- K87 已将系统 physics 改为 Clamping,避免原生 overscroll 回弹叠加。
- 但 `_refresh` 仍先执行 `_animateOffsetTo(_holdDistance)`,会把松手时的 D(例如 96)回收到 56。
- 用户感知为“页面已经弹回去”,实际是组件自身在刷新开始时主动缩短 offset。
## 范围
- ReelShort `lib/core/widgets/app_pull_to_refresh.dart`
- ReelShort `test/core/app_pull_to_refresh_test.dart`
- FruitServer `docs/plans/PROGRESS.md`
## 实现计划
1. 保留 `AlwaysScrollableScrollPhysics(parent: ClampingScrollPhysics())`,系统不移动 overscroll 内容。
2. 删除 `_holdDistance` 与刷新前的 56px 过渡动画。
3. 达到阈值松手后立即进入 refreshing,AnimationController 保持当前 D;刷新期间滚动通知和手势均忽略。
4. `onRefresh` 完成后再从 D 执行 200ms easeOut 回 0,指示器随 offset 淡出。
5. 未达阈值松手时新增 `_retracting` 状态,执行 200ms easeOut 回到 0,不触发 `onRefresh`。
## 测试计划
- 达阈值测试:记录松手 offset D,挂起 300ms 后仍等于 D;刷新中重复下拉不改变 D、不增加调用。
- complete 后断言 offset 回 0、指示器消失。
- 未达阈值测试:松手后立即开始回弹,100ms 时 offset 介于 0 与 D 之间,最终回 0 且 `onRefresh` 未调用。
- 断言 `AppPullToRefresh.physics.parent` 为 `ClampingScrollPhysics`。
## 风险与处理
- 保持 D 时下拉越高,内容下移越明显,但这是用户松手时的真实位置,刷新完成后才回收。
- 未达阈值回弹期间通过 `_retracting` 忽略新滚动通知,避免动画目标被手势覆盖。
- 不逐个页面改动,所有使用共享 physics 与组件的页面自动生效。
## Git
- ReelShort 从 `develop` 创建 `fix/pull-refresh-freeze`。
- 提交:`fix(ui): 下拉刷新刷新期间冻结下拉位移`。
- 作者:`Zhou Weidong <502333560@qq.com>`。
- `--no-ff` 合回 `develop` 并 push,不使用 force push,不执行 `git add -A`。
- FruitServer 追加 PROGRESS 留痕;不安装真机,完成后等待用户验收。
+23
View File
@@ -23616,3 +23616,26 @@ $ flutter test --no-pub
```
解读:ReelShort 静态检查零告警,514 条测试全部通过。未安装真机,等待用户验收。
## 2026-10-21 ReelShort:K87.1 下拉刷新刷新期间冻结位移
- 修正分支:`fix/pull-refresh-freeze`,从 ReelShort develop `01bef7f` 创建。
- 功能提交:`35860e0 fix(ui): 下拉刷新刷新期间冻结下拉位移`。
- develop 合并提交:`e6f3497 merge: 合并 K87.1 下拉刷新冻结位移修复`,已推送 `01bef7f..e6f3497`。
- 经核对,K87 已将 `AppPullToRefresh.physics` 改为 `AlwaysScrollableScrollPhysics(parent: ClampingScrollPhysics())`,K87.1 保留该配置,不再依赖原生 overscroll 位移。
- 删除 `_holdDistance` 和刷新前“当前距离 → 56px”的动画。达到阈值松手后 AnimationController 冻结在松手距离 D,刷新期间忽略滚动通知并阻止手势,`onRefresh` 完成后才从 D 执行 200ms easeOut 回 0。
- 未达阈值松手新增 `_retracting` 状态,从当前距离执行 200ms easeOut 回 0;回弹期间忽略新手势,不触发刷新。
- 测试红灯复现:达阈值 D=96 时旧实现会变成 56,偏差 40;未达阈值松手旧实现立即从 30 变为 0。修复后 pending 300ms 仍保持 D,重复下拉不增加调用;未达阈值 100ms 时 offset 仍介于 0 与 D 之间,最终回 0。
门禁原始输出:
```text
$ dart analyze lib test
Analyzing lib, test...
No issues found!
$ flutter test --no-pub
01:35 +515: All tests passed!
```
解读:ReelShort 静态检查零告警,515 条测试全部通过。未安装真机,等待用户验收。