切换需保留滚动位置与输入状态
别名: 折叠保状态 · 滚动位置保留 · configuration change restore
概念解释
尺寸跳了之后,人还停在刚才那一行、那一个输入框里。保留滚动位置与输入状态要求折叠或展开不把阅读进度清零、不丢掉未提交的字、不关掉正在用的键盘或选区。布局可以换成单栏或双栏,任务对象、滚动偏移、插入符、已打的字必须是同一份。这不是「应用别被杀掉」——进程可以重建,重建后要回到同一坐标。铰链上放不放内容是另一件事;这里只谈跳变两端的状态是不是还连着。
机制
折叠常触发配置变化:窗口度量一换,界面树被拆掉再挂上一棵适配新尺寸的。默认路径会把列表滚到 0、清空焦点、把未提交的编辑丢在被销毁的控件里。人记得的是「大约看到这一段」「字已经打了一半」,这是外部记忆加工作记忆。坐标归零后,人会以为文档被刷新了,或以为自己操作失败。输入状态更脆:组合输入的拼写缓冲、密码框里的明文切换、选中的一段文字,都活在控件实例上,实例一换就没了。虚拟列表还要恢复数据窗口,只记一个像素值、窗口却从第一页重拉,中间那段对象还不在,会出现空白或错行。媒体播放的位置、滚动之外的分页进度,属于同一类必须带走的坐标。
怎么研究
把长列表滚到中部、在字段里打到一半、保持插入符,然后折叠或展开。比较完整恢复、只恢复路由不恢复偏移、以及重建后回到顶部三种。
自变量:界面是否随配置变化销毁、是否按锚点(行 id、字符偏移)而不是按像素恢复、输入法缓冲是否随控件一起走。 因变量:位置误差(行号或字符)、已输入文本丢失、焦点是否还在原字段、继续任务的时间。
不要只问「还在同一页吗」,要问「是不是还在刚才那一行、那一个字」。实验室里若允许先提交再折,测不到未提交态。折叠动画期间不要采集点击,等稳定后再看恢复是否已完成,否则会把动画中的中间帧当成丢失。
边界
折叠期间内容被外部改写(新消息插到顶、协作删了当前行)时,精确像素可能没意义,应把原锚点滚回视口;锚点没了就落到邻近并说明。搜索结果这类一次性列表,恢复必须连查询一起,否则坐标对着另一串命中。用户在折叠前故意回到顶部,恢复成中部反而是错的——保存的是离开时的状态,不是「一个我们认为更好的位置」。播放中的视频若因解码器随表面重建而暂停,应自动接着播,不要把暂停当成用户意图。
怎么落地
- 在折叠前记下路由、锚点(行 id 或字符偏移)、未提交文本、焦点字段和播放位置;新布局挂上后按锚点对齐,而不是只 set 一个旧像素。
- 虚拟列表同时恢复数据窗口,避免先空白再闪到中部。
- 输入框在重建后写回已打的字并恢复插入符;不要为了「干净」清掉未提交内容。
- 验证:滚到第 N 段、打半句、再折开。视口仍含第 N 段,半句还在,焦点还在该框。出现顶部、空框或要重新聚焦,状态就没带走。