【寻迹校园 HarmonyOS NEXT 实战 39】1280vp 临界点不丢状态:响应式断点往返的状态恢复测试

📅 2026/8/27 4:50:15
【寻迹校园 HarmonyOS NEXT 实战 39】1280vp 临界点不丢状态:响应式断点往返的状态恢复测试
本章导读这是“寻迹校园 HarmonyOS NEXT 实战”系列第 39 篇。本文结合Index.ets、HomePage.ets、xunji-responsive-focus-state-audit.md与xunji-exact-xl-breakpoint-input-audit.md复盘窗口在xl → lg → xl之间往返时如何保持搜索、筛选、左栏滚动、查询记录、候选预览与中间详情并说明 1278.95vp/1280vp 精确断点证据为什么仍不能替代实体 2-in-1 验收。上图为原创生成的断点测试插画不是项目截图。窗口变化只切换可见布局状态账本位于布局分支之上因此右栏暂时隐藏不等于候选状态被删除。一、断点 Bug 往往不是布局错而是状态重置页面从三栏缩到双栏再放大最容易出现的不是宽度计算错误而是搜索关键词被清空组合筛选面板收起左栏滚动回到顶部查询记录切回第一条中栏从候选详情跳回查询本身右栏恢复后忘记哪个候选已选中路由栈被新 Shell 重建重复触发 Service 初始化。这些问题的共同根因是把业务/交互状态放在只对某个断点存在的组件内部。二、本章验证的精确临界点测试设备是 2026-08-12 的 MateBook Pro API 22 模拟器VPR 为 1.9根窗口像素宽度逻辑宽度预期布局2430px1278.95vplg 双栏2432px1280vpxl 三栏由于物理像素是离散值2430px 无法精确得到 1279vp但 1278.95vp 足以证明1280分支下一档 2432px 恰好命中 1280vp。三、测试场景不是空页面缩放为了验证状态恢复测试先构造有意义的上下文在 xl 打开筛选面板滚动左侧记录列表选择一条查询记录在右栏点击候选 2确认中栏显示候选详情缩到 lg确认右栏隐藏但中栏仍是候选再放大到 xl确认筛选、滚动、查询和候选选择恢复。只验证“三栏出现/消失”无法发现状态问题。四、根宽度状态位于 Shell 之上Index保存LocalselectedTab:BottomTabBottomTab.HOME;LocaldataRevision:number0;LocalscreenWidth:number0;screenWidth只决定渲染哪种 ShellselectedTab与pathStack不属于某个 Shell 分支。窗口变化不会重新创建Index因此全局导航上下文得以保留。五、HomePage 状态也位于 compact/split 分支之上HomePage在 builder 之外保存Localkeyword:string;LocalselectedFilter:HomeReportFilterHomeReportFilter.ALL;LocalselectedCategory:string;LocalselectedAreaKeyword:string;LocalselectedTimeRange:HomeTimeRangeHomeTimeRange.ALL;LocalselectedColor:string;LocalfilterPanelVisible:booleanfalse;LocalselectedReportId:string;LocalpreviewReportId:string;compactHome()、splitScreenHome()和workspaceView只是消费这些状态没有各自创建副本。六、为什么状态必须高于 if 分支如果把previewReportId声明在右栏组件内部lg 布局不渲染右栏时组件会销毁恢复 xl 后只能重新选择默认候选。当前设计把预览 ID 放在HomePage右栏只是根据它显示选中边框。即使右栏暂时不存在中栏仍可以继续展示候选详情。七、xl → lg 时到底隐藏了什么当宽度从 1280vp 降到 1278.95vpworkspaceView从 true 变为 false右栏MatchResultsPage不再渲染左栏从 34% 变为 38%中栏从固定 44% 变为layoutWeight(1)selectedReportId不变previewReportId不变中栏仍用previewReportId加载详情。隐藏的是辅助视图不是业务选择。八、lg → xl 时如何恢复候选标记恢复到 1280vp 后右栏重新创建并接收selectedCandidateId:this.previewReportIdthis.selectedReportId?:this.previewReportId如果中栏仍在预览候选右栏对应卡片立即显示“正在中间预览”和品牌边框。恢复不依赖重新点击。上图把持久状态、短生命周期交互状态和布局可见性分开。lg 阶段只暂停右栏呈现查询与预览状态仍留在 HomePage。九、selectedReportId 与 previewReportId 的断点意义两者分别表示selectedReportId左栏查询来源previewReportId中栏当前详情。断点往返时查询来源必须保持候选预览也应保持。一个 ID 无法同时表达这两个事实会迫使页面在缩放时选择丢弃其中之一。十、筛选面板展开态为什么值得保留用户在 xl 展开组合筛选后缩小窗口通常只是调整窗口不代表取消任务。如果filterPanelVisible随布局重建变回 false用户会误以为筛选条件被清除。当前展开态保存在HomePage因此往返后仍保持。显示形式可以改变但用户意图不应被断点覆盖。十一、筛选值如何与列表刷新协调搜索或筛选变化会调用refreshReports()。刷新后页面先判断原查询是否仍在结果中constselectionAvailablethis.reports.some((report:ItemReport)report.idthis.selectedReportId);只有查询被筛掉时才选择新的第一条记录。窗口变化本身不调用重置筛选因此不会改变结果集合。十二、左栏滚动位置属于视图状态左栏 Scroll 在布局往返时保持位置是 2026-08-12 验收的一部分。滚动位置不是 Repository 数据也不需要写入数据库它属于当前页面会话的短生命周期状态。但如果整个HomePage被断点分支替换为不同页面实例Scroll 也会重建。当前实现保持同一HomePage只改变内部布局。十三、右栏滚动恢复为什么曾是 not applicable第一轮验收中最大化窗口内容高度约 942vp当前业务最多返回 3 条候选全部已经可见没有有效额外滚动距离因此“右栏滚动恢复”被标记为not applicable。后续精确 1280vp 验收在更窄右栏中注入滚动候选 2、候选 3 进入视口证明滚动容器可达。但这仍不是“滚动偏移在所有窗口往返中持久化”的完整证明。十四、Navigation 为什么不能随 Shell 重建新实例Phone、md、lg/xl 的外壳不同但pathStack是Index的单一字段。假如每个 builder 内部临时创建new NavPathStack()断点切换会丢失当前详情、发布或认领路径。共享路由栈让 Shell 切换只影响导航呈现不影响用户已经进入的流程。十五、业务初始化为什么不能绑定 onAreaChangeonAreaChange可能在窗口拖动过程中高频触发。当前回调只在宽度变化时更新数字不打开数据库、不请求匹配、不重建 Service。业务初始化发生在aboutToAppear()并通过现有 Service 统一执行。把 Repository 初始化放进宽度回调会形成请求风暴和状态闪烁。十六、边界判断要避免重叠与空洞当前范围为sm: width 600 md: 600 width 840 lg: 840 width 1280 xl: width 1280每个宽度只属于一个档位没有600vp同时命中两种布局也没有839.5vp落入空白。测试必须覆盖等号所在的点而不只测 500、900、1500 三个普通宽度。十七、Number(newArea.width) 的输入风险Area.width被转换为 number 后参与比较。实现应关注初次布局前screenWidth为 0宽度字符串能否稳定转换系统缩放产生小数 vp浮点值在 1280 附近的离散性同一个物理像素变化是否频繁跨界。本次 1278.95/1280 证据正是对小数逻辑宽度的实际检查。十八、为什么需要往返而不是单向切换单向lg → xl只能证明第三栏出现。xl → lg → xl才能检查隐藏组件是否销毁权威状态中栏是否保留候选右栏能否恢复选中态筛选与滚动是否仍在Tab 焦点链是否重新闭合列表是否被重复刷新。状态恢复测试必须包含“回到原布局”。十九、焦点状态与数据状态不能混为一谈断点切换后具体 DOM/ArkUI 节点可能被替换键盘焦点不一定能保持在完全相同的按钮上但查询、筛选和候选选择仍必须保持。测试应分别记录数据状态Report、候选、筛选值交互状态选中、展开、滚动焦点状态当前可聚焦节点与顺序路由状态页面栈布局状态sm/md/lg/xl。一项通过不能覆盖其他项。二十、2026-08-12 的验收结果xunji-responsive-focus-state-audit.md记录xl → lg → xl 状态恢复 passed筛选面板、左栏滚动、查询记录、候选 2 预览和中栏详情保持xl 焦点链在应用内闭环377vp Phone 回归 passed当时本地测试 15/15、APP 构建 passed。xunji-exact-xl-breakpoint-input-audit.md进一步记录1278.95vp 为 lg1280vp 为 xl候选点击联动 passedTab/ShiftTab 输入 passed右栏滚动 passed。二十一、为什么不能把旧构建结果当成今天的新构建上述记录来自明确日期和当时基线。当前文章重新读取了现有Index.ets与HomePage.ets确认状态结构仍存在但没有重新执行 2026-08-26 的 MateBook 模拟器安装与构建。因此文章引用“2026-08-12 验收 passed”不会写成“今天重新真机通过”。二十二、实体 2-in-1 仍需补哪些证据模拟器输入通道无法覆盖实体窗口吸附与系统缩放触控板滚动惯性鼠标焦点与 hover蓝牙键盘组合键外接显示器 DPI 切换睡眠恢复和多窗口生命周期折叠形态与铰链区域。这些项目应继续标记为not run直到出现相应设备记录。二十三、首发仅 Phone 对测试结论的影响当前 manifest 只声明 Phone。大屏断点测试属于保留能力的工程验证不等于当前 AGC 包面向 2-in-1 分发。后续恢复设备类型前应基于最终 release 包重新执行矩阵而不是直接复用开发阶段的模拟器结论。二十四、可自动化的状态断言断点测试可以把状态写成结构化断言before: width1280, queryA, previewC2, filterOpentrue shrink: width1278.95, rightPanelfalse, queryA, previewC2 restore: width1280, rightPaneltrue, queryA, previewC2, candidate2Selectedtrue截图用于视觉证据布局树/状态记录用于精确断言。只比较截图容易受字体、时间和动画影响。二十五、工程复盘布局可变用户意图必须稳定窗口变化是展示环境变化不是用户重新开始任务。查询、筛选、候选预览和路由表达用户意图生命周期应该高于 Shell 和右栏组件。将状态提升到稳定父组件后断点分支可以自由出现或消失而无需把所有状态写入全局存储或数据库。二十六、本文小结“寻迹校园”的 1280vp 状态恢复依赖两层稳定状态Index保存全局导航与宽度HomePage保存筛选、查询与预览lg/xl 分支只改变右栏可见性和列宽。selectedReportId与previewReportId的分离使候选详情在右栏隐藏期间仍能保留。2026-08-12 的 1278.95vp/1280vp 模拟器证据证明了当时的临界切换、往返状态和输入链路实体 2-in-1、外设、当前 release 包与商店设备支持仍需独立验证。系列导航第 39 篇 / 共 50 篇。上一篇《34%/44%/22% 三栏工作台》下一篇《键盘焦点与可访问名称》。