嵌入页面切回来,键盘为什么不再自己弹出:HarmonyOS 7 把焦点先留在根容器
·
嵌入页面切回来,键盘为什么不再自己弹出:HarmonyOS 7 把焦点先留在根容器
搜索面板嵌在 EmbeddedComponent 中。旧版本从详情页返回时,第一个 TextInput 会自动拿到焦点并拉起键盘;升级后键盘不弹了,开发者第一反应是“输入框失效”。其实 API 26 统一了层级页面切换时的焦点规则:未设置 defaultFocus、也没主动 requestFocus 时,焦点停在根容器,不再自动下发给第一个可获焦子节点。
新规则减少了意外弹键盘,但也会暴露那些把“第一个控件刚好是输入框”当成产品逻辑的页面。
验证边界:本文依据华为 2026-08-19 更新的 HarmonyOS 7(API 26)Beta1 行为变更说明。示例中的判定与状态模型已在宿主 Node.js 环境跑过断言;平台组件接入片段未在 API 26 SDK 或真机编译运行,不能替代目标设备验收。

两种进入方式不要混在一起
| 场景 | API 26 行为 | 是否应显式聚焦 |
| 外部走焦进入 EmbeddedUIExtensionAbility | 正常下发到首个可获焦节点 | 按交互设计决定 |
| 层级页面切换后焦点转入 | 默认停留根容器 | 需要自动输入时才设置 |
案例一:扫码结果页返回搜索页
返回后立即弹键盘可能遮住扫码结果,因此应该保留根容器焦点,让用户点输入框时再进入编辑。把意图写成状态,不依赖组件顺序:
type FocusIntent = 'preserve-root'|'resume-editor'|'user-request';
function shouldRequestInput(intent: FocusIntent, pageVisible: boolean, dialogOpen: boolean): boolean {
return pageVisible && !dialogOpen && (intent === 'resume-editor' || intent === 'user-request');
}
if (shouldRequestInput('preserve-root', true, false)) throw new Error('must not pop keyboard');
if (!shouldRequestInput('resume-editor', true, false)) throw new Error('resume should focus');
案例二:收银台回到验证码输入
用户刚从协议页返回,业务明确要求继续输入,此时可给目标 TextInput 设置稳定 id,在页面状态恢复完成后 requestFocus。不要用固定延时赌页面已经挂载。
type PageState = { appeared: boolean; restored: boolean; targetId?: string };
function focusTarget(state: PageState): string | null {
if (!state.appeared || !state.restored) return null;
return state.targetId ?? null;
}
if (focusTarget({appeared:true,restored:false,targetId:'codeInput'}) !== null) throw new Error('too early');
if (focusTarget({appeared:true,restored:true,targetId:'codeInput'}) !== 'codeInput') throw new Error('target');
平台页面中可以选择 .defaultFocus(true),也可以在 onAppear 后通过 FocusController.requestFocus(id) 主动请求。两者都应服务于明确交互,不要同时设置造成抢焦点。
还要检查哪些副作用
焦点变化会影响键盘、屏幕朗读、遥控器/键盘导航和焦点样式。验收时记录“焦点在哪个节点”,不能只记录键盘是否出现。弹窗、菜单打开时也不要把焦点强行拉回输入框。
发布前清单
- 为自动聚焦写出产品理由,而不是恢复旧行为。
- 目标节点使用稳定 id,页面销毁后取消延迟任务。
- 返回、外部走焦、首次进入分别测试。
- 覆盖键盘、无障碍和方向键操作。
- 在 API 26 目标设备验证真实焦点链。
官方依据
更多推荐

所有评论(0)