自定義導(dǎo)航欄左上角膠囊按鈕返回、首頁(yè)小房子

示例項(xiàng)目地址:https://github.com/Shay0921/header-navbar

在小程序中,從轉(zhuǎn)發(fā)出來的小程序消息卡片進(jìn)入,因?yàn)轫?yè)面棧中只有一個(gè),所以不會(huì)出現(xiàn)返回按鈕,對(duì)于一些電商平臺(tái)來說,當(dāng)商品被轉(zhuǎn)發(fā)后會(huì)很影響客戶查看其它產(chǎn)品和首頁(yè),這時(shí)候就需要使用自定義導(dǎo)航欄自己寫一個(gè)“膠囊按鈕”。如下圖所示:

從別的頁(yè)面點(diǎn)到商品頁(yè)時(shí)會(huì)有返回和首頁(yè)按鈕;


當(dāng)從分享頁(yè)進(jìn)入到商品頁(yè)時(shí),因?yàn)轫?yè)面棧只有一個(gè),所以只有首頁(yè)按鈕;


首先我們需要如何開啟自定義導(dǎo)航欄,查看手冊(cè)后會(huì)發(fā)現(xiàn)一個(gè)頁(yè)面配置項(xiàng):navigationStyle


之前的版本此配置項(xiàng)只能在app.js中配置,是全局的屬性,而現(xiàn)在可以在單獨(dú)的頁(yè)面json中配置,實(shí)現(xiàn)單獨(dú)頁(yè)面自定義導(dǎo)航欄。

整體思路

當(dāng)使用了navigationStyle:custom后,之前的頂部標(biāo)題欄會(huì)被刪除,右側(cè)的膠囊按鈕則會(huì)固定在右上角。然后在當(dāng)前頁(yè)面添加了三個(gè)view(狀態(tài)欄、標(biāo)題欄、主體內(nèi)容),可以看出三塊的布局,我直接寫死的高度:狀態(tài)欄20px,標(biāo)題欄44px。這個(gè)是自定義導(dǎo)航欄的關(guān)鍵,需要去計(jì)算這兩塊的高度,還有返回|首頁(yè)膠囊按鈕的位置?;A(chǔ)庫(kù) 2.1.0開始可以使用wx.getMenuButtonBoundingClientRect()來獲得右側(cè)膠囊按鈕的位置信息,而有了這個(gè)信息,就能相對(duì)的算出我們想要在左側(cè)添加的膠囊按鈕的位置。通過wx.getSystemInfoSync()中的statusBarHeight找到狀態(tài)欄的高度。


目錄結(jié)構(gòu)

全局變量

app.js

在app.js中要先獲得狀態(tài)欄高度和右側(cè)膠囊位置信息

這里需要注意wx.getMenuButtonBoundingClientRect(),并不是像wx.getSystmInfo一樣有success回調(diào)函數(shù),而是像對(duì)象一樣wx.getMenuButtonBoundingClientRect().height來使用。

組件代碼

headerNavbar.wxml? ??

為了適配不同手機(jī)屏幕,高度和膠囊按鈕的位置都需要在html里面賦值,下面會(huì)詳細(xì)的說明高度如何計(jì)算。在自定義導(dǎo)航欄組件中分為兩部分,一個(gè)是頂部的導(dǎo)航欄另一個(gè)是自己寫的loading。

因?yàn)樽远x導(dǎo)航欄是fixed到頂部的,為了保證不擋住下面的主體內(nèi)容,我們需要在導(dǎo)航欄和主體內(nèi)容之間添加一個(gè)跟導(dǎo)航欄相同的高度,class先叫做box。這樣可以保證導(dǎo)航欄不擋著主體內(nèi)容。但是會(huì)出現(xiàn)另一個(gè)問題,如果此頁(yè)面支持下拉刷新,那么導(dǎo)航欄會(huì)把小程序原生的loading樣式擋住,而在主體內(nèi)容的前面會(huì)出現(xiàn)一個(gè)空白的box,雖說不影響使用,但是在用戶看來會(huì)很奇怪,莫名其妙的多出來一塊,box只有在loading結(jié)束后才會(huì)上去。所以在這里需要自己手寫一個(gè)loading的動(dòng)畫效果放在組件的最底下,高度跟導(dǎo)航欄一樣。

可以看到下面的最終效果,藍(lán)色導(dǎo)航條下面的三個(gè)點(diǎn)是小程序原生loading,再下面三個(gè)小點(diǎn)是自己寫的loading。

而我們想要的效果則是,當(dāng)小程序原生的loading被當(dāng)時(shí),自己寫的loading就可以替代原生的loading

headerNavbar.js

狀態(tài)欄高度= app.globalData.systeminfo.statusBarHeight

需要注意膠囊位置信息的原點(diǎn)是在頁(yè)面的左上角,所以需要轉(zhuǎn)換一下,把原膠囊位置信息起名為膠囊,轉(zhuǎn)換后的叫做現(xiàn)膠囊。

/**

* iphone6 的膠囊位置信息

*

wx.getMenuButtonBoundingClientRect() 坐標(biāo)信息以屏幕左上角為原點(diǎn)

現(xiàn)膠囊上邊距 = 膠囊上邊界坐標(biāo) - 狀態(tài)欄高度

現(xiàn)膠囊右邊距 = 屏幕寬度 - 膠囊右邊界坐標(biāo)

現(xiàn)膠囊下邊距 = 膠囊下邊界坐標(biāo) - 膠囊高度 - 狀態(tài)欄高度

導(dǎo)航欄高度 = 膠囊下邊界坐標(biāo)+ 現(xiàn)膠囊下邊距

注意:膠囊下邊界坐標(biāo)包含了狀態(tài)欄、膠囊高度和狀態(tài)欄和膠囊高度之間的距離,因?yàn)槟z囊是居中在導(dǎo)航欄里的,所以上邊距與下邊距應(yīng)該一致,所以是膠囊下邊界坐標(biāo) - 膠囊高度 - 狀態(tài)欄高度。

通過getCurrentPages() 來判斷當(dāng)前頁(yè)面是否從分享頁(yè)進(jìn)入,因?yàn)槿绻麖姆窒眄?yè)進(jìn)入頁(yè)面棧中應(yīng)該只有一條數(shù)據(jù),在跳轉(zhuǎn)到其他頁(yè)面時(shí)頁(yè)面棧的length則會(huì)增加,在其他頁(yè)面就會(huì)顯示出返回和首頁(yè)按鈕。

注意:微信7.0.0支持wx.getMenuButtonBoundingClientRect(),如果想兼容低版本的微信,只能把導(dǎo)航欄的高度寫死,通過一些大佬的計(jì)算得出的高度:

'iPhone': 64,

'iPhone X': 88,

'android': 68

具體查看:

https://developers.weixin.qq.com/community/develop/doc/0006c012dc8028f04b070dd0551004

如果你使用wx.getMenuButtonBoundingClientRect()得到信息有小數(shù),如下所示

{height:24, width: 65.25, top: -0.5, bottom: -0.5, right: 101.25}

那么你可能是把開發(fā)工具中的視圖縮放了,還原成100%就正常了。


headerNavbar.wxss

引用組件頁(yè)面代碼

navigationStyle.json

先在需要使用自定義導(dǎo)航欄的頁(yè)面json中添加navigationStyle:custom

enablePullDownRefresh:true?????? ? 開啟下拉刷新

backgroundTextStyle: light是把loading的樣式改成白色,這樣就不會(huì)顯示出來loading的三個(gè)點(diǎn)

navigationStyle.wxml

navigationStyle.js

注意:雖說這么做在小程序開發(fā)工具中看起來都是對(duì)的,得到的導(dǎo)航欄高度也是64px但是在真機(jī)上測(cè)試后,還是有偏差,在iphone8 plus上高度是60px。

可以通過這張圖明顯看到差了幾px,如果你是單獨(dú)幾個(gè)頁(yè)面使用自定義導(dǎo)航,細(xì)心的用戶可能會(huì)發(fā)現(xiàn),但是基本不影響。如果是全局使用自定義導(dǎo)航,那就不存在這個(gè)問題了。

示例項(xiàng)目地址:https://github.com/Shay0921/header-navbar

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容