【HarmonyOS】输入框焦点控制实现键盘显隐和进入页面默认弹出键盘获取焦点设置
在 HarmonyOS 中,控制输入框的焦点与键盘显隐,核心思路是通过 defaultFocus 实现页面进入自动获焦,通过 focusControl.requestFocus 实现动态切换,并通过 onFocus / onBlur 监听状态变化。以下是具体实现方案。
一、核心原理
输入框(TextInput)与键盘的联动遵循一个基本规则:键盘的显隐与输入框的焦点状态绑定。 当一个输入框获得焦点时,系统软键盘会自动弹出;当它失去焦点时,键盘会收起 。
二、进入页面默认弹出键盘
在页面加载后,希望输入框自动获得焦点并弹出键盘,最直接的方式是使用 defaultFocus 属性。
typescript
TextInput()
.id('myInput')
.defaultFocus(true) // 页面首次进入时,该组件自动获焦,弹出键盘
.onFocus(() => {
console.log('输入框已获焦,键盘弹出');
})
注意事项:
-
defaultFocus仅在页面初次创建并第一次进入时生效。对于被if条件控制显隐的自定义组件,或二次进入页面时,它不会生效 。 -
若页面内多个组件设置了
defaultFocus(true),系统会以组件树深度遍历找到的第一个为准 。
API 11 行为变更:在 API 11 及之后版本,如果没有任何组件设置 defaultFocus(true),页面首次打开时默认焦点将落在根容器上,而不会自动聚焦到第一个可获焦的非容器组件 。
三、主动控制焦点与键盘显隐
当你需要动态控制键盘弹出或收起(如点击按钮让某个输入框获焦,或点击空白区域收起键盘)时,可以使用 focusControl。
1. 主动获取焦点(弹出键盘)
调用 requestFocus 方法,让焦点转移到指定的输入框上,从而拉起键盘。
typescript
// 推荐写法(API 12 及以上,可捕获错误码)
this.getUIContext().getFocusController().requestFocus('myInput');
// 或传统写法
focusControl.requestFocus('myInput');
应用场景:当某个输入框因被 if 隐藏后重新显示,需要自动获焦时,可在显示逻辑后调用此方法 。
2. 主动清除焦点(收起键盘)
调用 clearFocus 方法,将焦点强制转移到页面的根容器上,此时所有输入框失去焦点,键盘收起。
typescript
this.getUIContext().getFocusController().clearFocus();
另一种技巧:通过动态修改 focusable 属性为 false,也可以强制当前输入框失去焦点,焦点会转移到下一个可获焦的组件 。
四、监听焦点状态与键盘显隐
1. 监听焦点变化
通过 onFocus 和 onBlur 回调,可以精确感知输入框的获焦和失焦瞬间。
typescript
TextInput()
.onFocus(() => {
// 获焦逻辑:例如修改UI样式,记录埋点
})
.onBlur(() => {
// 失焦逻辑:例如校验输入内容
})
2. 监听键盘高度变化(判断键盘显隐)
除了焦点监听,有时业务需要监听键盘的弹出与收起(例如调整页面布局)。可以通过窗口模块监听键盘高度变化 。
typescript
import { window } from '@kit.ArkUI';
let windowClass: window.Window | undefined = undefined;
window.getLastWindow(this.context, (err, data) => {
windowClass = data;
// 监听键盘高度变化
windowClass.on('keyboardHeightChange', (height: number) => {
if (height > 0) {
console.log('键盘已弹出,高度为:' + height);
// 执行键盘弹出时的UI适配逻辑
} else {
console.log('键盘已收起');
// 执行键盘收起时的UI适配逻辑
}
});
});
五、进阶控制与特性
1. enableKeyboardOnFocus:获焦不弹键盘
默认情况下,输入框获焦就会弹键盘。若你希望输入框获得焦点(例如用于粘贴操作)但暂时不弹出键盘,可以将此属性设为 false 。
typescript
TextInput() .defaultFocus(true) .enableKeyboardOnFocus(false) // 获焦了,但不弹键盘
2. 自定义键盘:完全接管键盘逻辑
如果需要使用自定义组件替代系统键盘,可以利用 customKeyboard 属性。此时输入框获焦后,不会弹出系统键盘,而是显示你定义的自定义组件 。
typescript
@Builder
function MyCustomKeyboard() {
Column() {
Button('自定义按键1')
Button('自定义按键2')
}
.width('100%')
.backgroundColor(Color.Gray)
}
TextInput()
.customKeyboard(MyCustomKeyboard()) // 获焦后显示自定义键盘
六、常见问题 FAQ
1. 为什么 defaultFocus(true) 在自定义组件中不生效?defaultFocus 仅在页面(Page)首次创建时生效。如果自定义组件是在页面加载后动态渲染(如被 if 控制),需要使用 requestFocus 主动请求焦点 。
2. 如何调试复杂的焦点问题?
-
查看焦点树:通过
hdc shell "hidumper -s WindowManagerService -a '-w [winId] -focus'"可以输出当前界面的焦点树,*标记的节点即为当前获焦节点 。 -
过滤焦点日志:在真机上根据关键词
AceFocus|AceKeyboard过滤日志,有助于排查焦点与键盘的联动问题 。
更多推荐
所有评论(0)