小程序?qū)崿F(xiàn)自定義導(dǎo)航欄適配完美版
1、發(fā)現(xiàn)問題
小程序頁(yè)面自定義導(dǎo)航欄功能已經(jīng)開放有些日子了(還不知道這個(gè)功能的可以先>>了解一下),這極大的提升了小程序開發(fā)的自由度,相信不少小伙伴已經(jīng)使用過這個(gè)功能,同時(shí)也相信不少小伙伴在此功能開發(fā)過程中踩過同樣的一些坑:
- 機(jī)型多如牛毛:自定義導(dǎo)航欄高度在不同機(jī)型始終無法達(dá)到視覺上的統(tǒng)一;
- 調(diào)皮的膠囊按鈕:導(dǎo)航欄元素(文字,圖標(biāo)等)怎么也對(duì)不齊那該死的膠囊按鈕;
- 各種尺寸的全面屏,奇怪的劉海屏,簡(jiǎn)直要抓狂。
同樣的,這些問題也是小灰經(jīng)歷過的。但是小灰相信,辦法總比問題多,于是開始了自己的探究:
2、一探究竟
為了搞明白到底該怎么去適配,老規(guī)矩,我先翻了一波官方文檔,還別說,官方還真有這么一段介紹了相關(guān)細(xì)節(jié),>>詳情點(diǎn)擊:
從圖中分析,我們可以得到如下信息:
- Android跟iOS有差異,表現(xiàn)在頂部到膠囊按鈕之間的距離差了6pt
- 膠囊按鈕高度為32pt, iOS和Android一致
這。。。,好像并沒有什么L用啊??這僅僅是普通屏幕為參照的,ipx, 安卓全面屏完全沒介紹。
沉著冷靜,我們接著分析:
- 膠囊按鈕到狀態(tài)欄下邊緣這塊距離,好像是固定的?
- 安卓這個(gè)圖,好像有點(diǎn)奇怪?導(dǎo)航欄分為 狀態(tài)欄+標(biāo)題欄?
- 如果車兩個(gè)條件成立,那我們的問題是不是就解決了80%了?
那么我們來論證一下:
第一個(gè)問題:膠囊按鈕到狀態(tài)欄下邊緣的距離是不是固定的?
很簡(jiǎn)單,我們寫一個(gè)狀態(tài)欄,通過wx.getSystemInfoSync().statusBarHeight設(shè)置高度
為了好測(cè)量,我們?cè)O(shè)置狀態(tài)欄背景色為深色
js代碼:
var sysinfo = wx.getSystemInfoSync(); this.setData({ statusBarHeight:sysinfo.statusBarHeight })
wxml代碼:
<view class="status-bar" style="height:{{statusBarHeight}}px"></view>
wxss代碼:
.status-bar{ background: rgb(141, 71, 71); }
效果圖(iPhone6):
效果圖(iPhoneX):
效果圖(安卓):
是不是有點(diǎn)眉目了?是的,從截圖可以看出,iOS是一致的,但是Android好像有所差別。
那究竟距離是多少?我們用神器(微信截圖)來量一量:
Android:
iOS:
可以看出,iOS膠囊按鈕與狀態(tài)欄之間距離為:6px, Android為8px,并且經(jīng)過測(cè)量,iOS各機(jī)型,Android各機(jī)型結(jié)果一致(由于篇幅原因,就不一一展示截圖了,有興趣的可以自行測(cè)量)
第二個(gè)問題:導(dǎo)航欄分為 狀態(tài)欄+標(biāo)題欄?
通過對(duì)第一個(gè)問題的論證,很明顯能看出來確實(shí)是這樣的。并且通過第一個(gè)問題的測(cè)量結(jié)果以及官方提供的數(shù)據(jù),我們可以對(duì)標(biāo)題欄高度進(jìn)行計(jì)算:
- 導(dǎo)航欄高度 = 膠囊按鈕高度 + 狀態(tài)欄到膠囊按鈕間距 * 2
- Android導(dǎo)航欄高度 = 32px + 8px * 2 = 48px
- iOS導(dǎo)航欄高度 = 32px + 6px * 2 = 44px
*注:由于膠囊按鈕是原生組件,為表現(xiàn)一直,其單位在個(gè)系統(tǒng)都為px,所以我們的自定義導(dǎo)航欄各個(gè)高度的單位都必需是px(切記不能用rpx),才能完美適配。
3、解決問題
通過上述分析,相信小伙伴們都能有一個(gè)解決問題的思路了,在上代碼之前,小灰再給大家畫一下重點(diǎn):
- 寫自定義導(dǎo)航組件的時(shí)候,需要將組件結(jié)構(gòu)一分為二:狀態(tài)欄 + 標(biāo)題欄
- 狀態(tài)欄高度可通過wx.getSystemInfoSync().statusBarHeight獲取
- 標(biāo)題欄高度:安卓:48px,iOS:44px
- 單位必需跟膠囊按鈕一致,用px
話不多說,上代碼(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: '導(dǎo)航欄' }, 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: { // 通過獲取系統(tǒng)信息計(jì)算導(dǎo)航欄高度 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; }
運(yùn)行效果圖:
文字標(biāo)題:
圖片標(biāo)題:
4、總結(jié)
經(jīng)過小灰的一番論證以及實(shí)踐經(jīng)驗(yàn),最終總結(jié)出以上最終解決方案,但希望對(duì)小伙伴們有所幫助,如果小伙伴們覺得有用,記得給顆star哦 --> 點(diǎn)我,后續(xù)還會(huì)更新其他組件。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中函數(shù)的防抖與節(jié)流詳解
這篇文章主要為大家詳細(xì)介紹了JavaScript中函數(shù)的防抖與節(jié)流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02js實(shí)現(xiàn)的萬能flv網(wǎng)頁(yè)播放器代碼
這篇文章主要介紹了js實(shí)現(xiàn)的萬能flv網(wǎng)頁(yè)播放器代碼,以簡(jiǎn)單示例形式分析了JavaScript使用swfobject.js實(shí)現(xiàn)在線播放flv視頻的相關(guān)技巧,需要的朋友可以參考下2016-04-04moment.js使用方法總結(jié)(全網(wǎng)最全)
日常開發(fā)中通常會(huì)對(duì)時(shí)間進(jìn)行下面這幾個(gè)操作,比如獲取時(shí)間,設(shè)置時(shí)間,格式化時(shí)間,比較時(shí)間等等,下面這篇文章主要給大家介紹了關(guān)于moment.js使用方法的相關(guān)資料,需要的朋友可以參考下2024-03-03JavaScript使用encodeURI()和decodeURI()獲取字符串值的方法
這篇文章主要介紹了JavaScript使用encodeURI()和decodeURI()獲取字符串值的方法,實(shí)例分析了encodeURI()和decodeURI()函數(shù)解析字符串的相關(guān)技巧,需要的朋友可以參考下2015-08-08JS實(shí)現(xiàn)獲取圖片大小和預(yù)覽的方法完整實(shí)例【兼容IE和其它瀏覽器】
這篇文章主要介紹了JS實(shí)現(xiàn)獲取圖片大小和預(yù)覽的方法,結(jié)合完整實(shí)例形式分析了javascript針對(duì)不同瀏覽器處理圖片上傳與預(yù)覽等操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04webpack教程之webpack.config.js配置文件
本篇文章主要介紹了webpack教程之webpack.config.js配置文件 ,具有一定的參考價(jià)值,有興趣的可以了解一席2017-07-07layui的表單驗(yàn)證支持ajax判斷用戶名是否重復(fù)的實(shí)例
今天小編就為大家分享一篇layui的表單驗(yàn)證支持ajax判斷用戶名是否重復(fù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09JS實(shí)現(xiàn)本地存儲(chǔ)信息的方法(基于localStorage與userData)
這篇文章主要介紹了JS實(shí)現(xiàn)本地存儲(chǔ)信息的方法,基于localStorage與userData實(shí)現(xiàn)本地存儲(chǔ)的功能,需要的朋友可以參考下2017-02-02解決微信內(nèi)置瀏覽器返回上一頁(yè)強(qiáng)制刷新問題方法
微信內(nèi)置瀏覽器在返回上一頁(yè)面,且上一頁(yè)面包含AJAX代碼時(shí),頁(yè)面就會(huì)被強(qiáng)制刷新,極度影響用戶體驗(yàn)。而我們想要的效果是:返回上一頁(yè)面時(shí),頁(yè)面還停留在原來的狀態(tài),AJAX獲取到的數(shù)據(jù)還在,滾動(dòng)條也在原來的位置。下面跟著小編一起來看下吧2017-02-02