收藏
回答

关于状态栏(statusBar)、导航栏(navBar)、底部安全区域高度的计算问题?!

测试使用的Android设备:小米10至尊纪念版

苹果设备:iPhone X

微信开发工具的模拟器:iPhone X


将手机分为四个区域,分别是“状态栏(statusBar)、导航栏(navBar)、内容区域、底部安全区域(bottomSafe)”,如图所示


已知前提如下

  1. statusBar的高度可以通过wx.getWindowInfo().statusBarHeight获取到
  2. navBar的高度等于胶囊高度+上下边距
  3. wx.getWindowInfo().safeArea.height的值表示“内容区域 + 导航栏”的高度


要探讨的问题

当navigationStyle为custom时,以上已知全部成立,但是为default时,第二条已知似乎有问题


正确的表现(navigationStyle: custom)

首先来看代码在不同设备、系统下正常的表现(高度全部占满,无纵向滑动条出现)


各文件代码

<!-- index.wxml -->
<view class="status-bar" style="height: {{statusBarHeight}}px;"></view>
<!-- <view class="nav-bar" style="height: {{navBarHeight}}px;"></view> -->


<view class="safe" style="height: {{safeHeight}}px;"></view>

<view class="bottom-safe" style="height: {{bottomSafeHeight}}px;"></view>


// index.js
Page({
  data: {
    statusBarHeight0,
    navBarHeight0,
    safeHeight0,
    bottomSafeHeight0,
  },
  onLoad() {
    // 获取的数值单位是px
    const windowInfo = wx.getWindowInfo();
    const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
    console.log(windowInfo);
    console.log(menuButtonInfo);


    let statusBarHeight = windowInfo.statusBarHeight;
    let navBarHeight = menuButtonInfo.height + (menuButtonInfo.top - statusBarHeight) * 2;
    let safeHeight = windowInfo.safeArea.height;
    let bottomSafeHeight = windowInfo.screenHeight - windowInfo.safeArea.height - statusBarHeight;
    this.setData({
      statusBarHeight,
      navBarHeight,
      safeHeight,
      bottomSafeHeight,
    });
    console.log("statusBarHeight", statusBarHeight);
    console.log("navBarHeight", navBarHeight);
    console.log("safeHeight", safeHeight);
    console.log("bottomSafeHeight", bottomSafeHeight);
  },
});



/* index.wxss */
page {
  background-color: red;
}

view {
  width100%;
}


.status-bar {
  background-colorrgb(55150187);
}


.nav-bar {
  background-color: bisque;
}


.safe {
  background-color: burlywood;
}


.bottom-safe {
  background-colorrgb(59112209);
}



// index.json
{
  "usingComponents": {},
  "navigationStyle""custom"
}



当navigationStyle为default时,状态栏和导航栏都会使用微信默认的,所以应该把自己写的状态栏和导航栏的view删除,因为safeHeight还包含了导航栏高度,所以内容区域的高度应该是safeHeight - navBarHeight

<!-- index.wxml就变成了这样 -->
<!-- <view class="status-bar" style="height: {{statusBarHeight}}px;"></view> -->
<!-- <view class="nav-bar" style="height: {{navBarHeight}}px;"></view> -->


<view class="safe" style="height: {{safeHeight-navBarHeight}}px;"></view>
as
<view class="bottom-safe" style="height: {{bottomSafeHeight}}px;"></view>


此前,模拟器和真机上的表现是一直的,但是在这里,就不一致了

模拟器上出现了滚动条,iPhone真机表现高度都正常,Android真机表现底部缺少了1像素(背景是红色的,可以看到底部出现了1像素高度的红色)


猜测这个问题是因为导航栏(navBar)高度计算不对导致的,间接导致了内容区域高度不正确


之前导航栏的高度是胶囊高度+胶囊上下边距,上下边距相等

胶囊左上角到状态栏顶边的垂直距离如图所示(蓝色线段),代码为:wx.getMenuButtonBoundingClientRect().top

胶囊左上角到状态栏顶边的垂直距离 减去 状态栏的高度 就是一个边距的值,所以

menuButtonInfo.height + (menuButtonInfo.top - statusBarHeight) * 2

就是导航栏的高度,但是nagivationStyle为default时,似乎就不是这么计算的了?请问官方,这时候导航栏的高度是怎么计算的呢?


以上代码已上传到代码片段

参考的文章

  1. https://developers.weixin.qq.com/community/develop/article/doc/00008a245604d8a1a8ce322345bc13
  2. https://developers.weixin.qq.com/community/develop/article/doc/0000ecde0e49a85a314c9d44d51013


回答关注问题邀请回答
收藏

1 个回答

  • 黄思程
    黄思程
    08-29

    如果是为了适配安全区域,用 css env safe-area-inset-* 实现更佳

    08-29
    有用
    回复 2
    • Kevin
      Kevin
      08-29
      这应该是IOS系统特有的吧?Android系统还得靠计算
      08-29
      回复
    • 黄思程
      黄思程
      09-04回复Kevin
      安卓也支持
      09-04
      回复
登录 后发表内容