IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    HarmonyOS开发案例-界面组件在软键盘弹出时避免遮挡

    小鱼发表于 2024-02-15 03:45:54
    love 0

    场景说明

    在应用开发中,我们经常会遇到这样的场景:当我们点击一个输入框时,系统会自动弹出软键盘,但是软键盘却会遮挡住输入框或者其他重要的控件。为了解决这个问题,现有的常用策略会在软键盘弹出时,根据输入框的位置,把整个页面向上移动一段距离,从而让输入框能够完全显示在屏幕上。然而,这种方法并不完美,其他控件比如确认按钮仍有可能被软键盘挡住,使得用户无法完成操作。本案例将针对此问题提供一种简单而有效的解决方案。

    效果呈现

    运行环境

    本例基于以下环境开发,开发者也可基于其他适配的版本进行开发:

    • IDE: DevEco Studio 3.1.1 Release
    • SDK: 3.1.0(API 9)

    实现思路

    要想解决页面遮挡的问题,我们首先要了解它的原因:当我们点击输入框时,系统会弹出软键盘,这时候软键盘会占用一部分屏幕空间,导致显示区域和软键盘区域重叠。软键盘区域属于系统规避区域。除了软键盘区域之外,还有一些其他的系统规避区域,比如状态栏、刘海屏和手势区域等。如果想让应用能够适应这些系统规避区域的变化,我们需要监听这些区域的变化事件并且根据这些区域的尺寸,动态地调整应用的显示区域,重新绘制页面。

    开发步骤

    1. 创建一个简单的输入验证码界面,它包含了文本框、输入框和确认按钮。这个界面的问题是,当我们点击输入框时,系统会弹出软键盘,但是软键盘却会挡住确认按钮,使得我们无法完成操作。
    @Entry
    @Component
    struct Index {
      @State screenHeight: number = 0;
      build() {
        Row() {
          Column() {
            Text('请输入短信验证码')
              .fontSize(30)
              .margin({
                bottom:'50'
              })
            TextInput()
              .width('70%')
              .height('150px')
              .margin({
                bottom: '30'
              })
            Button('确定')
              .width('70%')
              .margin('20px')
          }
          .width('100%')
        }
        .width('100%')
        .height('100%')
      }
    }
    1. 创建一个变量screenHeight,并把它赋值为当前显示区域的高度。这样,我们就可以在后面根据需要来修改这个变量的值,从而改变显示区域的高度。
    @State screenHeight: number = 0;
    
    window.getLastWindow(getContext(this)).then(currentWindow =>{
          let property = currentWindow.getWindowProperties();
          let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD);
          // 初始化显示区域高度
          this.screenHeight = px2vp(property.windowRect.height - avoidArea.bottomRect.height);
        })
    })
    
    1. 监听系统规避区域的变化事件,判断是否是由于软键盘的弹出或收起导致的。如果是,则就获取软键盘的高度。然后,将screenHeight的值设置为原始高度减去软键盘的高度。这样,显示区域就会缩小,避免和软键盘重叠。
    window.getLastWindow(getContext(this)).then(currentWindow =>{
        let property = currentWindow.getWindowProperties();
        currentWindow.on('avoidAreaChange', async data => {
            if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) {
                return;
            }
            this.screenHeight = px2vp(property.windowRect.height - data.area.bottomRect.height);
        })
    })

    完整代码

    import window from '@ohos.window';
    
    @Entry
    @Component
    struct Index {
     @State screenHeight: number = 0;
    
     aboutToAppear() {
       window.getLastWindow(getContext(this)).then(currentWindow =>{
         let property = currentWindow.getWindowProperties();
         let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD);
         // 初始化显示区域高度
         this.screenHeight = px2vp(property.windowRect.height - avoidArea.bottomRect.height);
         // 监视软键盘的弹出和收起
         currentWindow.on('avoidAreaChange', async data => {
           if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) {
             return;
           }
           this.screenHeight = px2vp(property.windowRect.height - data.area.bottomRect.height);
         })
       })
     }
    
     build() {
       Row() {
         Column() {
           Text('请输入短信验证码')
             .fontSize(30)
             .margin({
               bottom:'50'
             })
           TextInput()
             .width('70%')
             .height('150px')
             .margin({
               bottom: '30'
             })
           Button('确定')
             .width('70%')
             .margin('20px')
         }
         .width('100%')
       }
       .width('100%').height(this.screenHeight)
     }
    }


沪ICP备19023445号-2号
友情链接