From 22fc17330538a403af9d3499f95bf3d982ba7492 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Wed, 21 Oct 2026 15:14:20 +0800 Subject: [PATCH] =?UTF-8?q?docs(plans):=20=E8=AE=B0=E5=BD=95=20K87=20?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E5=88=B7=E6=96=B0=E5=AE=8C=E6=88=90=E5=90=8E?= =?UTF-8?q?=E5=9B=9E=E5=BC=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-10-21-K87-pull-to-refresh-hold.md | 47 +++++++++++++++++++ docs/plans/PROGRESS.md | 24 ++++++++++ 2 files changed, 71 insertions(+) create mode 100644 docs/plans/2026-10-21-K87-pull-to-refresh-hold.md diff --git a/docs/plans/2026-10-21-K87-pull-to-refresh-hold.md b/docs/plans/2026-10-21-K87-pull-to-refresh-hold.md new file mode 100644 index 0000000..bf3f055 --- /dev/null +++ b/docs/plans/2026-10-21-K87-pull-to-refresh-hold.md @@ -0,0 +1,47 @@ +# 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 留痕;不安装真机,完成后等待用户验收。 diff --git a/docs/plans/PROGRESS.md b/docs/plans/PROGRESS.md index ca6fb79..c0d0a8f 100644 --- a/docs/plans/PROGRESS.md +++ b/docs/plans/PROGRESS.md @@ -23592,3 +23592,27 @@ $ flutter test --no-pub ``` 解读:ReelShort 静态检查零告警,514 条测试全部通过。未安装真机,等待用户验收。 + +## 2026-10-21 ReelShort:K87 下拉刷新完成后回弹 + +- 功能分支:`feat/pull-to-refresh-hold`,从 ReelShort develop `d39d8d4` 创建。 +- 功能提交:`45e8707 feat(ui): 下拉刷新完成后才回弹`。 +- develop 合并提交:`01bef7f merge: 合并 K87 下拉刷新完成后回弹`,已推送 `d39d8d4..01bef7f`。 +- `AppPullToRefresh.physics` 从 Bouncing 改为 Clamping,系统不再自行提供 overscroll 位移;内容下拉统一由 `AnimationController` 和 `Transform.translate` 控制,避免刷新保持与系统回弹叠加。 +- 松手达到阈值后,当前位移用 200ms easeOut 过渡到固定 hold 56px;刷新 pending 期间保持 56px,忽略滚动通知并通过 `IgnorePointer` 阻止重复手势。 +- `onRefresh` 完成后用 200ms easeOut 回弹到 0,指示器透明度随位移降低并淡出,最终状态恢复 idle;刷新中固定显示进度圈与 `refreshingLabel`。 +- 已核对 11 个使用方均传入 `AppPullToRefresh.physics`,剧场、榜单、钱包、收藏、下载、通知、新剧、观看记录等页面自动生效。 +- 测试使用挂起 Completer 覆盖:松手瞬间 offset 高于 56、200ms 后稳定在 56、pending 再等 300ms 仍保持 56、刷新中重复下拉不增加调用且不改变保持高度、完成后回 0 且指示器消失。 + +门禁原始输出: + +```text +$ dart analyze lib test +Analyzing lib, test... +No issues found! + +$ flutter test --no-pub +00:49 +514: All tests passed! +``` + +解读:ReelShort 静态检查零告警,514 条测试全部通过。未安装真机,等待用户验收。