小程序页面自定义导航栏功能已经开放有些日子了(还不知道这个功能的能够先>>了解一下),这极大的提高了小程序开发的自由度,相信很多小伙伴已经使用过这个功能,同时也相信很多小伙伴在此功能开发过程当中踩过一样的一些坑:html
一样的,这些问题也是小灰经历过的。可是小灰相信,办法总比问题多,因而开始了本身的探究:git
为了搞明白到底该怎么去适配,老规矩,我先翻了一波官方文档,还别说,官方还真有这么一段介绍了相关细节,>>详情点击:github
从图中分析,咱们能够获得以下信息:小程序
这。。。,好像并无什么L用啊??这仅仅是普通屏幕为参照的,ipx, 安卓全面屏彻底没介绍。
沉着冷静,咱们接着分析:微信
那么咱们来论证一下:app
第一个问题:胶囊按钮到状态栏下边缘的距离是否是固定的?xss
很简单,咱们写一个状态栏,经过wx.getSystemInfoSync().statusBarHeight设置高度
为了好测量,咱们设置状态栏背景色为深色
js代码:flex
var sysinfo = wx.getSystemInfoSync(); this.setData({ statusBarHeight:sysinfo.statusBarHeight })
wxml代码:ui
<view class="status-bar" style="height:{{statusBarHeight}}px"></view>
wxss代码:this
.status-bar{ background: rgb(141, 71, 71); }
效果图(iPhone6):
效果图(iPhoneX):
效果图(安卓):
是否是有点眉目了?是的,从截图能够看出,iOS是一致的,可是Android好像有所差异。
那究竟距离是多少?咱们用神器(微信截图)来量一量:
Android:
iOS:
能够看出,iOS胶囊按钮与状态栏之间距离为:6px, Android为8px,而且通过测量,iOS各机型,Android各机型结果一致(因为篇幅缘由,就不一一展现截图了,有兴趣的能够自行测量)
第二个问题:导航栏分为 状态栏+标题栏?
经过对第一个问题的论证,很明显能看出来确实是这样的。而且经过第一个问题的测量结果以及官方提供的数据,咱们能够对标题栏高度进行计算:
*注:因为胶囊按钮是原生组件,为表现一直,其单位在个系统都为px,因此咱们的自定义导航栏各个高度的单位都必需是px(切记不能用rpx),才能完美适配。
经过上述分析,相信小伙伴们都能有一个解决问题的思路了,在上代码以前,小灰再给你们画一下重点:
话很少说,上代码(gitHub地址):
js:
Component({ properties: { background: { type: String, value: 'rgba(255, 255, 255, 1)' }, color: { type: String, value: 'rgba(0, 0, 0, 1)' }, titleText: { type: String, value: '导航栏' }, titleImg: { type: String, value: '' }, backIcon: { type: String, value: '' }, homeIcon: { type: String, value: '' }, fontSize: { type: Number, value: 16 }, iconHeight: { type: Number, value: 19 }, iconWidth: { type:Number, value: 58 } }, attached: function(){ var that = this; that.setNavSize(); that.setStyle(); }, data: { }, methods: { // 经过获取系统信息计算导航栏高度 setNavSize: function() { var that = this , sysinfo = wx.getSystemInfoSync() , statusHeight = sysinfo.statusBarHeight , isiOS = sysinfo.system.indexOf('iOS') > -1 , navHeight; if (!isiOS) { navHeight = 48; } else { navHeight = 44; } that.setData({ status: statusHeight, navHeight: navHeight }) }, setStyle: function() { var that = this , containerStyle , textStyle , iconStyle; containerStyle = [ 'background:' + that.data.background ].join(';'); textStyle = [ 'color:' + that.data.color, 'font-size:' + that.data.fontSize + 'px' ].join(';'); iconStyle = [ 'width: ' + that.data.iconWidth + 'px', 'height: ' + that.data.iconHeight + 'px' ].join(';'); that.setData({ containerStyle: containerStyle, textStyle: textStyle, iconStyle: iconStyle }) }, // 返回事件 back: function(){ wx.navigateBack({ delta: 1 }) this.triggerEvent('back', {back: 1}) }, home: function() { this.triggerEvent('home', {}); } }})
wxml:
<view class='nav' style='height: {{status + navHeight}}px'> <view class='status' style='height: {{status}}px;{{containerStyle}}'></view> <view class='navbar' style='height:{{navHeight}}px;{{containerStyle}}'> <view class='back-icon' wx:if="{{backIcon}}" bindtap='back'> <image src='{{backIcon}}'></image> </view> <view class='home-icon' wx:if="{{homeIcon}}" bindtap='home'> <image src='{{homeIcon}}'></image> </view> [连接描述][10] <view class='nav-icon' wx:if="{{titleImg}}"> <image src='{{titleImg}}' style='{{iconStyle}}'></image> </view> <view class='nav-title' wx:if="{{titleText && !titleImg}}"> <text style='{{textStyle}}'>{{titleText}}</text> </view> </view> </view>
wxss:
.navbar{ position: relative } .back-icon, .home-icon{ width: 28px; height: 100%; position: absolute; transform: translateY(-50%); top: 50%; display: flex; } .back-icon{ left: 16px; } .home-icon{ left: 44px } .back-icon image{ width: 28px; height: 28px; margin: auto; } .home-icon image{ width: 20px; height: 20px; margin: auto; } .nav-title, .nav-icon{ position: absolute; transform: translate(-50%, -50%); left: 50%; top: 50%; font-size: 0; font-weight: bold; }
运行效果图:
文字标题:
图片标题:
通过小灰的一番论证以及实践经验,最终总结出以上最终解决方案,但但愿对小伙伴们有所帮助,若是小伙伴们以为有用,记得给颗star哦 --> 点我,后续还会更新其余组件。
若是你们有更好的方案或者以为小灰的方案有问题,欢迎你们留言。