主要邏輯就是動態獲取設備的 statusBarHeight 和 titleBarHeight,來設置導航欄的高度和 paddingTopcss
ip6html
ipxjson
loading小程序
導航欄是一個組件,自定義組件經過 properties 得到 prop 參數的,組件還須要維護 statusBarHeight,titleBarHeight 和 navigatorHeight(實際沒用到) 這三個 dataapp
經過在小程序 ready 生命週期內調用 setBarHeight 來動態獲取這三個 data 變量佈局
Component({ properties: { title: { type: String, default: 'default title' }, ifShowBtn: { type: Boolean, default: true } }, data: { statusBarHeight: 0, titleBarHeight: 0, navigatorHeight: 0 }, ready: function () { this.setBarHeight() },
組件還有三個方法,這三個方法分別是:設置狀態欄和標題欄高度的 setBarHeight、動態獲取狀態欄和標題欄高度的 getBarHeight,以及判斷是否爲 IOS 系統。post
由於判斷是否爲 IOS 系統纔可以設置 titleBarHeight,iPhone 或 iPad 的這個值爲 44,安卓的統一設置爲 48 便可flex
methods: { // 設置狀態欄和標題欄高度 setBarHeight: function () { this.isIOS().then(this.getBarHeight).then(res => { this.setData({ statusBarHeight: res.statusBarHeight, titleBarHeight: res.titleBarHeight, navigatorHeight: res.navigatorHeight }) }) }, // 動態獲取狀態欄高度和標題欄高度 getBarHeight: function (isIOS) { return new Promise((resolve, reject) => { wx.getSystemInfo.call(this, { success: res => { let statusBarHeight = res.statusBarHeight let titleBarHeight = isIOS ? 44 : 48 resolve({ statusBarHeight, titleBarHeight, navigatorHeight: statusBarHeight + titleBarHeight }) }, failure: res => { reject('error getting systeminfo') } }) }) }, // 判斷是否爲 IOS 系統 isIOS: function () { return new Promise((resolve, reject) => { wx.getSystemInfo.call(this, { success: res => { if (res.model.indexOf('iPhone') > -1 || res.system.indexOf('iOS') > -1) { resolve(true) } else { resolve(false) } }, failure: res => { reject('error getting systeminfo') } }) }) }
另外,在得到這些變量以後能夠存入到 app 的 globalData 對象中,每次只須要從這個對象獲取變量便可動畫
而後編寫 wxml:this
<view style="height: {{titleBarHeight}}px; padding-top: {{statusBarHeight}}px;"> <view class="header" style="height: {{titleBarHeight}}px; padding-top: {{statusBarHeight}}px;"> <view wx:if="{{ifShowBtn}}" class="header-btn"> <view class="btn-item">B</view> <view class="btn-item">H</view> </view> <view class="header-title">{{title}}</view> </view> <view class="loading">loading...</view> </view>
自定義導航欄的高度就是 titleBarHeight,paddingTop 的值就是 statusBarHeight
由於自定義導航欄是 fixed 元素,所以這個 class 爲 header 的 view 元素設置樣式以下:
.header { display: flex; align-items: center; position: fixed; /* fixed 所以在 wxml 中還須要再次設置一遍 height 和 paddingTop */ top: 0; background: #fff; width: 100%; z-index: 9999; }
header-title 是一個絕對定位的元素,須要設置樣式,將其居中:
.header-title { position: absolute; left: 50%; transform: translateX(-50%) }
最後還須要解決 pullDownRefresh 的加載動畫問題,若是沒有修復這個問題會出現一個大的空白
首先須要設置 app.json
{ "pages": [ "pages/index/index" ], "window": { "backgroundTextStyle": "light", "navigationStyle": "custom", "enablePullDownRefresh": true, "navigationBarBackgroundColor": "#fff", "navigationBarTextStyle": "black" } }
而後增長組件 wxml 中 class 爲 loading 的元素這個就是自定義加載動畫
而後增長樣式:
.loading { height: 100%; display: flex; justify-content: center; align-items: center; }
flex 佈局並居中便可
最後設置 navigator.json 將模塊定義爲組件
{ "component": true }
在頁面中使用:
修改配置文件:
{ "usingComponents": { "navigator": "../../components/navigator/navigator" } }
修改 wxml 文件:
<navigator ifShowBtn="{{true}}" title="the navigator"></navigator> <view class="container"> <!-- ...... --> </view>
參考: