HarmonyOS 鸿蒙Next中如何定位键盘弹出后原UI布局错乱问题
HarmonyOS 鸿蒙Next中如何定位键盘弹出后原UI布局错乱问题
【问题现象】
在键盘弹出时,用户界面布局出现错乱现象,比如键盘遮挡输入框、Tab被键盘顶起、导航栏被顶出屏幕等问题。
效果如下:
上图为初始状态,下图为错误的场景:
【背景知识】
- 软键盘布局适配场景介绍,键盘避让机制。 参考链接:键盘布局适配。
- layoutWeight:组件在父组件剩余空间的布局权重。 参考链接:layoutWeight。
- expandSafeArea:控制组件扩展其安全区域。 参考链接:expandSafeArea。
【定位思路】
键盘的避让模式 KeyboardAvoidMode 默认为OFFSET,此时键盘的避让效果为整体页面被顶起,符合问题现象。
【解决方案】
1. 使用RESIZE键盘避让模式
设置KeyboardAvoidMode值为RESIZE,此时页面中设置百分比宽高的组件会跟随页面压缩,直接设置宽高的组件会按设置的固定大小布局。
示例中List 容器使用layoutWeight(1),layoutWeight(number) 属性作用为组件在父组件主轴方向的布局权重,即占父组件容器在主轴方向上剩余区域的多少,自适应占满父组件剩余空间。此时键盘弹出时List组件高度会被压缩,其他组件的高度不变。而在RESIZE模式下,expandSafeArea设置不生效。
效果如下:最下方“Red Square Below”被键盘顶起,List组件高度被压缩。
2. 键盘弹出时控制组件是否避让
当不需要被顶起的组件被键盘顶起时,可通过expandSafeArea使该组件不避让键盘。需要注意,在KeyboardAvoidMode.RESIZE模式下,expandSafeArea属性不生效。
expandSafeArea意为扩大安全区域,KEYBOARD事件下,扩展TOP、BOTTOM区域,即该组件可以渲染到键盘的上下区域,此时该组件不避让键盘。
代码示例如下:
Blank() { // Blank为任意UI组件
}.expandSafeArea([SafeAreaType.KEYBOARD], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) // 意为该组件可以渲染到键盘遮盖的区域
效果如下:
上图中,底部的BottomTextArea未设置键盘避让,因此输入时仅该组件被顶起,其余组件未被顶起。
下图中,List设置了键盘避让,此时最下方的TextInput组件输入时,该输入组件被键盘遮挡。
3. 通过监听键盘高度或安全区域高度变化,手动处理UI布局
手动处理UI布局时,要注意容器组件的高度是否为固定高度,推荐使用layoutWeight属性自适应容器或组件高度。
当页面释放时,要注意关闭键盘事件监听。
代码示例如下:
aboutToAppear(): void {
this.setKeyboardHandler();
}
aboutToDisappear(): void {
// 关闭键盘高度监听,避免内存泄露
this.keyboardListenerWindow && this.keyboardListenerWindow.off('keyboardHeightChange');
}
setKeyboardHandler() {
window.getLastWindow(getContext(this)).then(currentWindow => {
this.keyboardListenerWindow = currentWindow;
currentWindow.on('keyboardHeightChange', (height:number) => {
this.keyboardHeight = px2vp(height);
// 后续根据键盘弹出的高度,自行计算组件布局。
})
})
}
效果如下:
图一:Bottom TextArea输入时,最底部“Red Square Below”被顶起。
图二:列表中奇数位输入框输入时,顶起位置为底部“Red Square Above”。
图三:列表中偶数位输入框输入时,顶起位置为List底部,即List下方“Red Square Above”被键盘遮挡。
【总结】
- KeyboardAvoidMode.RESIZE模式下,expandSafeArea设置将不起作用。
- 容器组件推荐使用百分比宽高度设置,如 width(‘100%’),或使用layoutWeight(1)。
- 列表类容器内的子组件若使用expandSafeArea,需要进行嵌套。因此,不推荐对列表容器内的子组件使用此属性。
- 使用各种监听时,务必在退出页面前取消监听,以避免潜在的内存泄漏。
- 在自定义页面顶起高度时,可以在容器最底部使用Blank组件,并根据需要被顶起的高度结合animateTo显式动画设置Blank组件的高度,以实现页面顶起效果。
更多关于HarmonyOS 鸿蒙Next中如何定位键盘弹出后原UI布局错乱问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html