【升级打怪实录】uniapp 打包为 apk,自定义导航栏自适应状态栏高度

430 阅读1分钟

需求

uniapp 内嵌 webview 加载 h5,最终打包为 apk,顶部导航栏由 h5 内部实现。

uniapp 打包为 apk 内部加载 webview 自定义状态栏.png

问题

不同手机状态栏高度不一致,自定义的导航栏顶部需要预留出手机状态栏的高度。

实现

在 uniapp 中做兼容处理。

<view class="content">
  <web-view src="https://xxxx.com/"></web-view>
</view>

0. uniapp pages.json 中设置自定义导航栏

    "navigationStyle": "custom"
  1. 获取 webview

    // 获取 webview
    getWebview() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const currentWebview = this.$scope.$getAppWebview();
          const webview = currentWebview.children()[0];
          if (webview) {
            resolve(webview)
          } else {
            reject('获取webview失败')
          }
        }, 100)
      })
    }
    

    为什么不采用 plus.webview.currentWebview() 获取 webview?

    因为该方法获取到的 webview 是 uniapp 框架内部自带的 webview,这个 webview 负责运行 UniApp 的框架逻辑(如生命周期管理、API 调用、事件分发等),不直接渲染页面内容。

  2. 获取系统状态栏高度并设置 webview 预留该高度。

    setWebviewTop(webview) {
      return new Promise((resolve, reject) => {
        // 获取系统状态栏高度
        const statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
        const querys = uni.createSelectorQuery().in(this);    
        querys.select('.content').boundingClientRect(res => {
          console.log('res:', res);
          if (res) {
            const height = res.height - statusBarHeight;
            // 设置 WebView
            webview.setStyle({
                top: statusBarHeight,
            });
            resolve('设置成功')
          } else {
            reject('设置失败')
          }
        }).exec();
      })
    }
    
  3. 方法调用

    onReady() {
      // #ifdef APP-PLUS
      this.getWebview().then(webview => {
        this.setWebviewTop(webview).then(() => {
            console.log('设置成功')
          }).catch(err => {
            console.log('设置失败: ', err)
          })
      })
      // #endif
    }
    

完整 demo