uni.getSystemInfoSync()同步获取statusBarHeight最稳妥,但H5返回0、小程序固定25、App返回真实像素;需结合getWindowInfo()和getMenuButtonBoundingClientRect()适配多端标题栏高度,并注意rpx换算基准。

uni.getSystemInfoSync() 直接读取 statusBarHeight
这是最常用、最稳妥的方式,适合在 onLoad 或组件 setup 中同步获取。返回值是对象,statusBarHeight 字段即所求值,单位为 px。
注意:该 API 在所有平台(H5 / App / 小程序)均可用,但数值含义不同:
- H5 端返回
0或无效值(浏览器无系统状态栏概念),不能直接依赖 - App 端(iOS/Android)返回真实像素高度,如 iPhone 15 Pro 为
59,部分安卓机为24~32 - 微信小程序端稳定返回
25(基础值),但实际渲染受胶囊按钮影响,仅靠它不够
示例:
const systemInfo = uni.getSystemInfoSync()
console.log('状态栏高度:', systemInfo.statusBarHeight) // 如 25、44、59 等uni.getWindowInfo() 获取更精准的窗口级 statusBarHeight
相比 getSystemInfoSync(),getWindowInfo() 是异步 API,返回当前窗口的实时信息,包含更准确的 statusBarHeight,尤其在 App 端横竖屏切换或动态调整后更可靠。
常见误用点:
- 未
await或未写success回调就直接取值 → 得到undefined - 在 H5 端调用后仍试图用该值做布局 → H5 的
statusBarHeight始终为0,应跳过计算 - 和
getMenuButtonBoundingClientRect()混用时未保证执行顺序 → 小程序中必须先有窗口信息,再取胶囊位置
推荐写法(带容错):
uni.getWindowInfo({
success: res => {
const height = res.statusBarHeight || 25
console.log('窗口状态栏高度:', height)
}
})MP-WEIXIN 平台下必须配合 getMenuButtonBoundingClientRect 计算标题栏总高
只拿 statusBarHeight 不够 —— 微信小程序的「导航栏」实际由两块组成:顶部状态栏 + 中间胶囊按钮区域(含标题)。真正需要留白/占位的高度是两者叠加后的「标题栏总高」。
关键公式:titleBarHeight = capsule.height + (capsule.top - statusBarHeight) * 2
为什么乘以 2?因为胶囊上下边距对称,从状态栏底到胶囊顶是空白,胶囊底到导航栏底又是等距空白。
实操要点:
- 必须在
#ifdef MP-WEIXIN条件编译块内调用uni.getMenuButtonBoundingClientRect() - 该 API 在某些低端安卓机或调试器中可能返回
null,需加判空 - 不要在
onLoad之前调用,否则可能因渲染未就绪而取不到坐标
简写封装示例:
function getNavBarHeight() {
const statusBar = uni.getSystemInfoSync().statusBarHeight
if (uni.getMenuButtonBoundingClientRect) {
const btn = uni.getMenuButtonBoundingClientRect()
if (btn) {
return btn.height + (btn.top - statusBar) * 2 + statusBar
}
}
return statusBar + 44 // fallback
}rpx 转换时容易忽略屏幕宽度基准
uni-app 的 rpx 是以 750rpx = 屏幕宽度为基准换算的。直接把 statusBarHeight(px)当 rpx 用,会导致不同设备上比例失真。
正确换算方式:
const info = uni.getSystemInfoSync() const px = info.statusBarHeight const rpx = (px / info.screenWidth) * 750
常见坑:
- 用
windowWidth替代screenWidth→ 前者是可滚动区域宽,可能小于屏幕物理宽度(尤其弹出键盘时) - 在 H5 端也强行换算 → H5 没有状态栏,
px为 0,换算后仍是 0,但逻辑上不该参与布局 - 未缓存换算结果,每次 render 都重复计算 → 影响性能,尤其列表页
建议在 onLaunch 中预计算并存入全局状态,后续直接读取。
不同平台对「状态栏」的理解差异最大,不是数值拿不到,而是拿回来不知道怎么用。最常被跳过的一步,是在条件编译里区分 H5 / App / 小程序三端逻辑,而不是写一个函数通吃所有环境。


















