赞
踩
最近在做小程序项目,需要用到自定义navigationBar,之前用过colorUI等组件库的navigationBar组件,但是现在想自己写一个,所以有了今天的小记
微信小程序一般来说有两个bar,一个导航栏,一个tabbar(小程序下方一排切换按钮),实现下方自定义tabbar的方法一般来说较为简单,现在着重叙述上方自定义导航栏的实现。
为什么要自定义navigationBar?
原生导航栏的限制
- 除了胶囊按钮以外,原生导航栏只会出现返回按钮和当用户打开的小程序最底层页面是非首页时,默认展示的“返回首页”按钮 。
- 原生导航栏的标题文字的颜色只有黑白。
- 布局无法改变,不能做定制。
产品需求
如果说原生导航栏的限制还不足以让你加入自定义导航栏,那么产品需求绝对是更大的推动力。
自定义导航栏除了不能自定义胶囊按钮以外,其他的范围都是程序员的掌控范围,所以使用自定义导航栏无疑可以满足产品的各种需求。
- 将需要自定义navigationBar页面的page.json的navigationBarTitleText去掉。
- 加上"navigationStyle":"custom",这样原生的导航栏就已经消失,甚至后退键也不会出现,需要自定义。
- 另外,早在2016年微信已经开始适配沉浸式状态栏,目前几乎所有的机型里微信都是沉浸式状态栏,也就是说去掉原生导航栏的同时,整个屏幕已经成为可编程区域。
3.以下图为例,上面的红色框是statusBar,高度已知;下面的红色框是正文内容,夹在中间的就是求解之一navigationBarHeight;而黄色的是原生胶囊按钮也是在垂直居中位置,高度为胶囊按钮基于左上角的坐标信息已知,不难得出,navigationBarHeight = 蓝色框高度 × 2 + 胶囊按钮.height。(蓝色框高度 = 胶囊按钮.top - statusBarHeight)
最后的计算公式为:navigationBarHeight = (胶囊按钮.top - statusBarHeight) × 2 + 胶囊按钮.height。navigationBar 距屏幕上方的距离即为navigationBarHeight。
这种计算方法在各种机型以及安卓ios都适用。
针对"wx.getMenuButtonBoundingClientRect()"获取错误或者获取数据为0的极少数情况,只能够去模拟,对于android,一般navigationBarHeight为48px,而对于ios一般为40px,所有机型的胶囊按钮高度是32px笔者也是通过网上很多的文章和自测得出的,这种误差一般可以忽略。当然最理想的就是微信可以hold住所有机型,呵呵。最后提醒一下仅以真机为准,开发者工具的bug就更多不说了。
app.js
- //计算导航栏高度
- const { statusBarHeight, platform } = wx.getSystemInfoSync()
- const { top, height } = wx.getMenuButtonBoundingClientRect()
-
- // 状态栏高度
- wx.setStorageSync('statusBarHeight', statusBarHeight)
- // 胶囊按钮高度 一般是32 如果获取不到就使用32
- wx.setStorageSync('menuButtonHeight', height ? height : 32)
-
- // 判断胶囊按钮信息是否成功获取
- if (top && top !== 0 && height && height !== 0) {
- //获取成功进行计算
- const navigationBarHeight = (top - statusBarHeight) * 2 + height
- // 导航栏高度
- wx.setStorageSync('navigationBarHeight', navigationBarHeight)
- } else {
- //获取失败使用默认的高度
- wx.setStorageSync(
- 'navigationBarHeight',
- platform === 'android' ? 48 : 40
- )
- }
navigationBar.js
- // 状态栏高度
- statusBarHeight: wx.getStorageSync('statusBarHeight') + 'px',
- // 导航栏高度
- navigationBarHeight: wx.getStorageSync('navigationBarHeight') + 'px',
- // 胶囊按钮高度
- menuButtonHeight: wx.getStorageSync('menuButtonHeight') + 'px',
- // 导航栏和状态栏高度
- navigationBarAndStatusBarHeight: wx.getStorageSync('statusBarHeight') +
- wx.getStorageSync('navigationBarHeight') +
- 'px',
- //标题
- title: '积分游戏'
navigationBar.wxml
- <view class="navigation-container" style="{{'height: ' + navigationBarAndStatusBarHeight}}">
- <!--空白来占位状态栏-->
- <view style="{{'height: ' + statusBarHeight}}"></view>
- <!--自定义导航栏-->
- <view class="navigation-bar" style="{{'height:' + navigationBarHeight}}">
- <!-- 这里就是导航栏 你可以将你想要的样式放到这里-->
- <view class="navigation-buttons" style="{{'height:' + menuButtonHeight}}">
- <image class="nav-img" src='/images/back.svg'/>
- ...其余自定义button
- </view>
-
- <view class="navigation-title" style="{{'line-height:' + navigationBarHeight}}">{{title}}</view>
- </view>
- </view>
- <!--空白占位fixed空出的位置-->
- <view style="{{'height: ' + navigationBarAndStatusBarHeight}}; background: #ffffff"></view>
navigationBar.wxss
/* navigationBar.wxss */ .navigation-container { position: fixed; width: 100%; z-index: 99; top: 0; left: 0; background-color: #ffffff; } .navigation-bar { position: relative; display: flex; flex-direction: row; align-items: center; } .navigation-buttons { display: flex; align-items: center; margin-left: 20rpx; border: 1px solid rgba(0, 0, 0, 0.05); box-sizing: border-box; border-radius: 30rpx; background-color: transparent; } .nav-img{ height: 32rpx; width: 32rpx; } .navigation-title { position: absolute; left: 208rpx; right: 208rpx; text-align: center; font-size: 32rpx; font-weight: bold; color: #000000; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
wx.getSystemInfo()获取到的参数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。