小程序頁面自定義導航欄功能已經開放有些日子了(還不知道這個功能的能夠先>>瞭解一下),這極大的提高了小程序開發的自由度,相信很多小夥伴已經使用過這個功能,同時也相信很多小夥伴在此功能開發過程當中踩過一樣的一些坑: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哦 --> 點我,後續還會更新其餘組件。
若是你們有更好的方案或者以爲小灰的方案有問題,歡迎你們留言。