开发者工具里突然出现「wx.getSystemInfo / getSystemInfoSync 已废弃」的黄字,自定义导航栏却还是对不齐胶囊,或者用 windowHeight 算出来的页面底部被 Home 条挡住------这多半不是「接口坏了」,而是还在用一把大而全的旧接口,去量几件已经拆开的尺寸。较新的基础库把系统信息拆成了窗口、设备、应用和开关几组同步接口。下面按「先看黄字和错位分别出在哪 → 用新接口按需取值并兼容旧基础库 → 用菜单按钮矩形把自定义导航算准 → 高度、安全区和横竖屏收口」来接。
1. 先分清:是废弃提示,还是高度、胶囊真的算错
不要一看到废弃提示就把所有 getSystemInfoSync 删掉再重写一遍。先判断卡在哪一类:
- 只是提示废弃:功能正常,但开发者工具或真机日志在告诫旧接口会在后续基础库移除。这时优先替换调用,而不是先改布局公式。
- 高度算错 :底部按钮被挡住、列表少一截、100vh 感觉的全屏其实溢出或留白。常见原因是把
screenHeight和windowHeight混用,或没减掉状态栏、安全区。 - 胶囊对不齐 :自定义导航栏的标题、返回按钮和右上角官方胶囊高低不一,甚至重叠。这通常不是「再调一次系统信息」能修,而要同时用窗口信息和
wx.getMenuButtonBoundingClientRect()。
getSystemInfo 把窗口尺寸、设备型号、基础库版本、授权开关塞在同一个返回值里,调用一次看起来省事,但字段含义在不同机型、开发者工具和 PC 端并不一致,也是官方拆分接口的原因。
2. 用拆分后的同步接口按需取值,旧基础库再回退
较新基础库里,这几组接口是同步的,直接返回对象,不必再写 success 回调:
wx.getWindowInfo():和布局有关的尺寸,例如pixelRatio、screenWidth/screenHeight、windowWidth/windowHeight、statusBarHeight、safeArea、screenTop。做导航栏、全屏页、安全区,优先用它。wx.getDeviceInfo():品牌、型号、系统、平台等设备信息。不要拿它来算像素高度。wx.getAppBaseInfo():基础库版本、宿主、语言、主题、字号等。对比SDKVersion、适配暗黑模式,用这一组。wx.getSystemSetting():系统蓝牙、定位、Wi-Fi、屏幕方向等开关。wx.getAppAuthorizeSetting():相册、定位、麦克风、通知等授权状态,和wx.getSetting互补。
旧基础库没有这些接口时,再回退到 getSystemInfoSync,不要一上来就假设新接口一定存在:
js
function getWindowInfoCompat() {
if (typeof wx.getWindowInfo === 'function') {
return wx.getWindowInfo()
}
const sys = wx.getSystemInfoSync()
return {
pixelRatio: sys.pixelRatio,
screenWidth: sys.screenWidth,
screenHeight: sys.screenHeight,
windowWidth: sys.windowWidth,
windowHeight: sys.windowHeight,
statusBarHeight: sys.statusBarHeight || 0,
safeArea: sys.safeArea,
screenTop: sys.screenTop || 0
}
}
function getAppBaseInfoCompat() {
if (typeof wx.getAppBaseInfo === 'function') {
return wx.getAppBaseInfo()
}
const sys = wx.getSystemInfoSync()
return {
SDKVersion: sys.SDKVersion,
language: sys.language,
version: sys.version,
theme: sys.theme,
host: sys.host,
fontSizeSetting: sys.fontSizeSetting
}
}
建议在 App 启动时算一次并缓存到全局,页面里不要每次 setData 或 onShow 都同步取一遍。尺寸在同一次冷启动里通常不会变;真正会变的是横竖屏和窗口变化,这时再在 wx.onWindowResize 里更新。
注意:getDeviceInfo 里部分敏感字段在较新基础库可能需要额外声明或权限,和布局无关的型号信息不要放在每个页面的首屏路径上顺手取。
3. 自定义导航栏要对齐胶囊,不能只靠 statusBarHeight
只拿 statusBarHeight + 44 当导航高度,在部分 Android、iPad、PC 端和开发者工具里会对不齐。官方胶囊的位置才是标尺,用 wx.getMenuButtonBoundingClientRect() 取出 top、height、right:
js
function getNavBarMetrics() {
const win = getWindowInfoCompat()
const menu = wx.getMenuButtonBoundingClientRect() || {}
const statusBarHeight = win.statusBarHeight || 0
const menuHeight = menu.height || 32
const menuTop = menu.top || statusBarHeight + 4
const gap = Math.max(menuTop - statusBarHeight, 0)
const navBarHeight = menuHeight + gap * 2
return {
statusBarHeight,
navBarHeight,
totalHeight: statusBarHeight + navBarHeight,
menuRight: (win.windowWidth || 0) - (menu.right || 0),
menuWidth: menu.width || 87,
windowWidth: win.windowWidth
}
}
计算时记住这几条:
- 左右留白要对着胶囊 。标题不要写到胶囊底下;右侧预留
windowWidth - menu.right,左侧返回按钮的垂直中心和胶囊中心对齐。 - 高度用「状态栏 + 两倍间隙 + 胶囊高度」 。间隙是
menu.top - statusBarHeight,不要写死 8 或 44。 - 开发者工具、PC 端、iPad 的胶囊位置和手机不同。公式要吃真实矩形,不要按某款 iPhone 的截图像素反推。
- 菜单按钮矩形偶发为 0 。极少数时机(过早在
App.onLaunch里取、或窗口尚未就绪)会拿到空值。判空后用statusBarHeight做一次兜底,并在首页onReady再算一次。
自定义导航开启时,页面还要在 json 里设 navigationStyle: custom,并给页面根节点加上 totalHeight 的 padding-top,避免内容顶到胶囊后面。
4. 屏幕高度、安全区和横竖屏不要混用字段
布局算错,经常是字段选错,而不是接口没调用成功:
screenHeight是整屏,windowHeight是可用窗口 。有原生导航栏时,windowHeight通常已经去掉了导航;自定义导航时则接近整屏可用高度。用错会表现为「底部按钮被顶出屏幕」或「下面空出一截」。- 底部安全区看
safeArea。全面屏的 Home 指示条不能靠经验值 34。可用高度更稳的算法是:以窗口底部为准,再取safeArea.bottom与窗口高度的差值作为safeAreaBottom。没有safeArea时再按 0 处理,不要给所有安卓机统一加 34。 - 全屏页还要看
screenTop。从自定义窗或半屏进入时,窗口不一定从屏幕顶端开始。 - rpx 换算用
windowWidth / 750。不要混用screenWidth,在有调试条或分栏时会偏。 - 横竖屏会变 。监听
wx.onWindowResize,或在页面onResize里重新取getWindowInfo并更新导航和安全区,不要假设启动时的缓存永远正确。 - 真机和开发者工具不一致。工具里的状态栏、胶囊和安全区都是模拟值。上线前用 iOS、Android 各一台,把「系统导航 / 自定义导航 / 横屏 / 有 TabBar / 无 TabBar」走一遍。
底部固定栏可以写成:
js
function getSafeAreaBottom() {
const win = getWindowInfoCompat()
const safe = win.safeArea
if (!safe || !win.windowHeight) return 0
return Math.max(win.windowHeight - safe.bottom, 0)
}
5. 上线前核对
- 新基础库走
getWindowInfo/getAppBaseInfo等拆分接口,旧基础库才回退getSystemInfoSync,不要只删警告不兼容。 - 自定义导航用菜单按钮矩形计算高度和左右留白,标题和返回按钮垂直对齐胶囊,判空并在
onReady复核。 - 页面高度、全屏和底部按钮分清
screenHeight、windowHeight和safeArea,不要给所有机型写死 44 或 34。 - 尺寸启动时缓存,横竖屏和窗口变化时再更新;不要在每个
setData里同步取系统信息。 - 真机验证系统导航与自定义导航、有无 TabBar、横屏、开发者工具与正式版是否一致。
系统信息已经按用途拆开了。窗口尺寸负责排版,设备信息负责识别机型,应用信息负责基础库和主题。把自定义导航对准胶囊,再把安全区留给底部操作,废弃提示和「高度算错、胶囊对不齐」就可以一次性收口。
本文由 DEVDIY 整理。我们日常做微信小程序定制与上线前检查时,会把系统信息改成「按用途拆开取值,自定义导航对准胶囊,安全区留给底部操作」,避免只靠一条旧的同步接口去算所有布局。