[微信小程序]navigationStyle设置为custom后,自定义导航栏适配不同屏幕
UPDATE 2022/11/27
这篇文章内容已经过时,不再具有参考意义。
实际上实现起来非常简单,只需要调用wx.getMenuButtonBoundingClientRect()
方法获取胶囊的位置信息,再给相关的 wxml 节点加上合适的高度即可,例如:
<!-- 假如这是页面标题 -->
<view class="title" style="margin-top:{{胶囊距离顶部的高度}};height:{{胶囊自身高度}}px"></view>
/* wxss */
.title{
display: flex;
align-items: center;
}
以下是原内容
navigationStyle
(官方文档)设置为custom
后,导航栏消失,可以自定义导航栏。
在不同的手机上,胶囊到屏幕顶部的距离是不一样的,尤其是刘海屏,这个距离会很大。所以自定义导航栏的高度不能写死。页面主体部分不能被右上角的胶囊覆盖;为了美观,自定义导航栏的标题最好也和胶囊在水平上对齐。所以,自定义导航栏的高度需要适配。
思路很简单,获取胶囊的位置,让导航栏的高度等于胶囊底边到屏幕顶端的高度,记为h
。另外,自定义导航栏的底边应该超出胶囊底边,目的是留一些空白,这样更加协调。所以,还要给h
加上一个合适的数值。
翻阅了微信官方文档,没找到哪里规定了胶囊底边的留白高度。所以,我在iPhone 6S
上找了一个小程序,截屏,手动量了一下胶囊底边到内容区域的高度为16px
:
所以就定了留白高度是16px
。其实这个高度可以根据自己的需要和审美来定。
但还有一个问题。16px
是在宽度为750px
的截图上测量的,因为iPhone 6S
屏幕的物理像素是750px
,所以截图就是750px。但在浏览器和小程序中,iPhone 6S
的逻辑宽度
是375
,正好是750的一半。所以实际设置css高度的时候,16px
也要除以2
。其实这个2
就是pixelRatio
。
我们以16
为基准,除以设备的pixelRatio
,就能得到实际的留白像素数。
注意:wx.getMenuButtonBoundingClientRect()等API返回的数值都是以
px
为单位的
所以上面讨论的都是px
,要和rpx
分清
下面是具体实现。
小程序运行过程中,屏幕参数是不会变的,所以,在小程序onLaunch
中获取一次相关数据,然后存起来就行了:
app.js
:
...
onLaunch: function() {
if (wx.canIUse('getMenuButtonBoundingClientRect')) {
let sysInfo = wx.getSystemInfoSync();
let rect = wx.getMenuButtonBoundingClientRect();
let navBarHeight = rect.bottom + 16 / sysInfo.pixelRatio;
// 存储胶囊位置信息
wx.setStorageSync('menuButtonRect', rect);
// 存储自定义导航栏的高度
wx.setStorageSync('navBarHeight', navBarHeight);
} else {
wx.showToast({
title: '您的微信版本过低,界面可能会显示不正常',
icon: 'none',
duration: 4000
});
}
},
...
新建一个组件叫做nav
:
组件nav
的wxml
:
<view class="nav-box" style="height:{{height}}px">
<view class="title">这是标题</view>
</view>
组件nav
的js
:
...
properties: {
height: {
type: Number,
value: 80 // 默认值
}
}
...
...
lifetimes: {
attached() {
this.setData({
height: wx.getStorageSync('navBarHeight')
})
}
}
...
然后,页面只要引用这个nav
组件就可以了。
现在nav
组件已经可以正常适配绝大多数的设备了。受限于手头测试设备的限制,和微信接口的不稳定,可能有个别设备会适配失败。
这里只是适配了自定义导航栏的高度,其他的问题就不在本文讨论范围内了。
如果您有不同的看法或者任何意见,欢迎评论或者联系我。
End
使用rect.top 更加精准
这篇文章已经过时了,当时是第一次做,弄复杂了,现在很容易就做出来……