HarmonyOS 鸿蒙Next 半模态框动态设置高度,当软键盘弹出时偶尔布局异常

发布于 1周前 作者 yibo5220 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 半模态框动态设置高度,当软键盘弹出时偶尔布局异常

实现思路:

用半模态实现弹框,根据键盘高度动态计算半模态框的高度,避免键盘弹出顶起半模态框导致内容显示不全。

image

代码说明:

绿色为bindsheet的配置颜色:

.bindSheet($$this.isShow, this.SubComment(), {
  backgroundColor: Color.Green
})

半模态框结构:

Column() {
  Scroll(this.scroller) {
    Column() {
      Row().backgroundColor(Color.Red)
      Row().backgroundColor(Color.Blue)
      Row().backgroundColor(Color.Yellow)
    }
  }
  .height(`calc(${this.screenHeight}vp - ${this.textHeight}vp - ${this.bottomRectHeight}vp)`)

  TextInput({
    placeholder: '请输入内容'
  })
    .height(this.textHeight)
    .backgroundColor(Color.White)

  Blank()
    .height(this.bottomRectHeight)
}
.width('100%')
.height(this.screenHeight)

完整代码

import { window } from '@kit.ArkUI';

@Component
export struct BindSheetPage {
  @State private isShow: boolean = false
  @State private screenHeight: number = 0
  @State private bottomRectHeight: number = 0
  private textHeight = 50
  private scroller: Scroller = new Scroller()

  aboutToAppear(): void {
    window.getLastWindow(getContext(this)).then(currentWindow => {
      let property = currentWindow.getWindowProperties();
      // 导航条区域的高度
      let avoidIndicatorArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
      let bottomRectHeight = px2vp(avoidIndicatorArea.bottomRect.height);
      this.bottomRectHeight = bottomRectHeight
      console.log('==== init bottomRectHeight:' + this.bottomRectHeight.toString())
      // 状态栏的高度
      let avoidTopArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
      let topRectHeight = avoidTopArea.topRect.height; // 获取状态栏区域高度
      console.log('==== init topRectHeight:' + topRectHeight.toString()) //输出可以看到键盘的高度
      // 键盘的高度
      let avoidKeyboardArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD);
      // 初始化显示区域高度
      this.screenHeight = px2vp(property.windowRect.height - avoidKeyboardArea.bottomRect.height - topRectHeight);
      console.log('==== init screenHeight:' + this.screenHeight.toString())

      // 监视软键盘的弹出和收起
      currentWindow.on('avoidAreaChange', data => {
        if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) {
          return;
        }
        const keyboardHeight = data.area.bottomRect.height // 键盘高度
        this.bottomRectHeight = keyboardHeight ? 0 : bottomRectHeight // 键盘抬起时,底部安全区域设为0
        this.screenHeight = px2vp(property.windowRect.height - keyboardHeight - topRectHeight);
        console.log('==== screenHeight:' + this.screenHeight.toString()) //输出可以看到键盘的高度
      })
    })
  }

  @Builder
  SubComment() {
    Column() {
      Scroll(this.scroller) {
        Column() {
          Row() {
            Text('1').fontColor(Color.White)
          }
          .width('100%')
          .height(300)
          .backgroundColor(Color.Red)

          Row() {
            Text('2').fontColor(Color.White)
          }
          .width('100%')
          .height(300)
          .backgroundColor(Color.Blue)

          Row() {
            Text('3').fontColor(Color.White)
          }
          .width('100%')
          .height(300)
          .backgroundColor(Color.Yellow)
        }
      }
      .height(`calc(${this.screenHeight}vp - ${this.textHeight}vp - ${this.bottomRectHeight}vp)`)
      .width('100%')

      TextInput({
        placeholder: '请输入内容'
      })
        .width('100%')
        .height(this.textHeight)
        .backgroundColor(Color.White)

      Blank()
        .width('100%')
        .height(this.bottomRectHeight)
    }
    .width('100%')
    .height(this.screenHeight)
  }

  build() {
    Column() {
      Button('打开bindSheet')
        .onClick(() => {
          this.isShow = true
        })
        .bindSheet($$this.isShow, this.SubComment(), {
          height: '100%',
          backgroundColor: Color.Green
        })
    }
    .justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%')
    .backgroundColor($r('app.color.contact_background'))
  }
}

更多关于HarmonyOS 鸿蒙Next 半模态框动态设置高度,当软键盘弹出时偶尔布局异常的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

我之前遇到过类似的场景,半模态中点击输入框 弹出键盘后,模态框中的布局会整体向上滑动一段距离。

我试过两种解决办法,第一种:给输入框绑定onEditChange事件,输入框有焦点时,计算出半模态框的高度,高度不要使用LARGE,高度自己计算出来就行。这样内容就不会滑上去。

第二种是,半模态中最外部布局高度设为自适应.height(‘auto’), 在内部第一个组件上添加

.expandSafeArea([SafeAreaType.KEYBOARD]),输入框也绑定

可以参考一下~

.expandSafeArea([SafeAreaType.KEYBOARD])。

更多关于HarmonyOS 鸿蒙Next 半模态框动态设置高度,当软键盘弹出时偶尔布局异常的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


姓名

张三

职位

软件工程师

所在城市

北京

自我介绍

一个热爱编程的开发者,专注于前端技术。

个人照片

有复现步骤吗 一直没复现

cke_399.png

点快点,我这边多试几次弹出、收起键盘必现。

还是没复现,我看下其它伙伴是否有遇到,

针对HarmonyOS鸿蒙Next半模态框在软键盘弹出时偶尔出现的布局异常问题,可以尝试以下方法进行调整:

  1. 监听软键盘状态:通过系统提供的API监听软键盘的弹出和收起状态。当软键盘弹出时,动态调整半模态框的高度,确保内容不被遮挡。

  2. 调整布局参数:在软键盘状态变化时,根据键盘高度动态修改半模态框的布局参数(如LayoutParams),确保布局适配。

  3. 使用约束布局:如果当前布局不是使用约束布局(ConstraintLayout),考虑切换到约束布局。约束布局提供了更强大的布局控制和约束能力,有助于解决布局异常问题。

  4. 检查布局层级:确保半模态框的布局层级正确,避免被其他视图遮挡或干扰。

  5. 避免硬编码高度:尽量不要在代码中硬编码半模态框的高度,而是通过布局文件或动态计算来设置高度,以提高布局的适应性。

如果以上方法仍无法解决布局异常问题,可能是由于具体的布局实现或系统版本差异导致的。此时,建议直接联系官网客服获取更专业的技术支持。官网地址是:https://www.itying.com/category-93-b0.html

回到顶部