記一次小程序自定義導航欄及加載動畫的解決方案

20190320163636.png

記一次自定義導航欄及加載動畫的解決方案

主要邏輯就是動態獲取設備的 statusBarHeight 和 titleBarHeight,來設置導航欄的高度和 paddingTopcss

20190320162517.png

ip6html

20190320162529.png

ipxjson

20190320163458.png

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 的加載動畫問題,若是沒有修復這個問題會出現一個大的空白

20190320163140.png

20190320163157.png

20190320163205.png

首先須要設置 app.json

  • backgroundTextStyle 爲 light
  • navigationBarTextStyle 爲 black
{
  "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>

參考:

相關文章
相關標籤/搜索