HarmonyOS 鸿蒙Next 如何定位键盘弹出后原UI布局错乱问题 鸿蒙场景化案例

发布于 1周前 作者 sinazl 最后一次编辑是 5天前 来自 鸿蒙OS

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 组件的高度,以实现页面顶起效果。
1 回复

作为IT专家,针对HarmonyOS 鸿蒙Next中键盘弹出后原UI布局错乱的问题,可以通过以下方法进行定位和解决:

  1. 检查expandSafeArea属性:利用expandSafeArea属性扩展组件的安全区域,使页面整体布局在键盘弹出时保持不变。检查相关组件是否已正确应用此属性。
  2. 分析布局容器:确认是否使用了合适的布局容器(如DependentLayout、FlexLayout等),这些容器能自动调整子组件的位置和大小,以适应不同屏幕尺寸和分辨率。
  3. 动态计算布局:在代码中动态计算并设置组件的尺寸和位置,根据设备的实际尺寸和分辨率来调整布局。这通常涉及到在Activity或Fragment的回调方法中更新布局参数。
  4. 测试与调试:在不同尺寸和分辨率的设备或模拟器上测试应用,使用HarmonyOS的调试工具检查布局在运行时的情况,找出并修正可能导致布局错乱的问题。
  5. 查阅官方文档:了解关于布局和适配的最新最佳实践,确保为不同密度的屏幕提供适当分辨率的图片和图形资源。

如果上述方法均无法解决问题,可能是应用中存在其他特定问题或冲突。此时,建议直接联系官网客服以获取更专业的帮助。官网地址是:https://www.itying.com/category-93-b0.html

回到顶部