小程序开发中自定义导航栏
小程序布局
- 说到导航栏和自定义导航栏,就需要解释一下微信小程序的布局。使用小程序开发中的wx.getSystemInfoAsync()方法获取系统信息。
- 收到的一些信息可以上图看到(来自微信小程序的开发者文档)。上述宽度和高度属性例如当前设备屏幕高宽、可用高宽和saveArea是了解布局的有用信息。
- 上图是从systemInfo、刘海屏在Apple上获取的数据的实际表现。区域字面意思就是开发者可以控制的页面区域。上面黄色区域是手机状态栏,绿色区域是我们要自定义的导航栏。
- 可以看到导航栏位于安全区域顶部附近。如果使用原生导航栏,真正的可控区域是在导航栏下方。
- 事实上,我们定制的导航栏与太空舱在这个安全区域的配合最为和谐。造成这种情况的主要原因是微信使用了右上角的胶囊按钮作为内置组件。它只有黑白两种颜色,这意味着我们无法更改其大小、位置、透明度等,因此为了匹配胶囊按钮,自定义导航栏的位置通常会与胶囊按钮的位置匹配。上图所示的位置是一样的。
如何自定义导航栏?
删除原生导航栏。
- 从应自定义 navigationBar 页面的 page.json 文件中删除 navigationBarTitleText。
- 添加"navigationStyle": "custom"这样原生导航栏就没有了,连后退按钮都没有出现,需要自定义。
- 早在2016年,微信就开始适配沉浸式状态栏。目前微信几乎所有机型都有沉浸式状态栏,这意味着如果去掉原生导航栏,整个屏幕就变成了可编程区域。计算
NavigationBarHeight。
- 当然原生胶囊按钮是存在的,所以下一步是定义自定义导航栏的高度和位置。
- 状态栏和胶囊按钮的位置对于不同的型号和系统来说是不确定的,因此需要进行一定的计算才能安全地确定任何型号的位置。
- 使用wx.getSystemInfoSync()获取statusBarHeight,从而确定导航栏与导航栏顶部的最基本距离。
- 使用wx.getMenuButtonBoundingClientRect()获取小程序的胶囊信息(注意这个API有很多问题,不同端表现不一样,后面处理api调用会失败)根据以下坐标信息图以屏幕左上角为原点。
- 以下图为例。上面的红色方块是statusBar,高度已知;下面的红色字段是文本内容,中间是解决方案之一navigationBarHeight;黄色是原生的胶囊按钮,也处于垂直中心位置。 Elevation 是胶囊按钮。根据左上角的坐标信息,不难猜测,navigationBarHeight = 蓝框高度×2 + 胶囊按钮.height。 (蓝框高度 = Capsule 按钮顶部 - statusBarHeight)
- 最终计算公式为:navigationBarHeight )× 2 + Cap sule按钮。高度。 navigationBar 距屏幕顶部的距离navigationBarHeight。
- 此计算方法可适用于不同机型以及Android和iOS系统。
- 极少数情况下,出现错误“wx.getMenuButtonBoundingClientRect()”或数据为0时,只能进行模拟。对于 Android,navigationBarHeight 通常为 48 像素,对于 iOS,通常为 40 像素,而 胶囊按钮 的高度在所有型号上均为 32 像素。
代码实现
- 来获取本地信息并将其写入组件的附加生命周期。
// components/Navigation/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
navigationBarHeight: 40,
statusBarHeight:20,
},
/**
* 组件的方法列表
*/
methods: {
},
lifetimes: {
attached: function () {
const { statusBarHeight, platform } = wx.getSystemInfoSync();
const { top, height = 32 } = wx.getMenuButtonBoundingClientRect();// 胶囊按钮高度 一般是32 如果获取不到就使用32
// 判断胶囊按钮信息是否成功获取
if (top && top !== 0 && height && height !== 0) {
//获取成功进行计算
const navigationBarHeight = (top - statusBarHeight) * 2 + height;
console.log(navigationBarHeight)
// 导航栏高度
this.setData({
navigationBarHeight,
statusBarHeight
})
} else {
//获取失败使用默认的高度
this.setData({
navigationBarHeight: platform === "android" ? 48 : 40,
statusBarHeight
})
}
}
}
})
- 组件模板为
<view class="custom-nav" style="height: {{navigationBarHeight}}px;margin-top:{{statusBarHeight}}px;">
<view>
<image style="width: 40rpx;height:40rpx;" mode="" />
</view>
</view>
.navigationBar.wxml,样式如下:
.custom-nav{
background-color:palegoldenrod;
display: flex;
align-items: center;
}
.custom-nav__title{
margin:auto
}
外部页面引用组件如下:
.json 文件,引入具有 ❀No 属性的组件。 : "navigationStyle":"custom" 你要自定义
.wxml组件的代码如下:
<view>
<my-navigation></my-navigation>
<view class="page-container" style="background-color: rebeccapurple;">这里是页面内容</view>
</view>
最终效果
如果你想写一个比较通用的组件,可以指定传入的参数和样式根据您的需求 作者:let_code
来源:稀土开采黄金
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。