自定义微信小程序导航(兼容各种手机)

详细代码请见github,请点击地址,其中有原生小程序的实现,也有wepy版本的实现

了解小程序默认导航

如上图所示,微信导航分为两部分,第一个部分为statusBarHeight,刘海屏手机(iPhone X,小米8等)会比其他的手机高很多,第二部分为titleBarHeight,安卓和IOS的高度不同,但是IOS高度是一样的,IOS高度是一样的,

所以我们要实现一个兼容不同手机的导航必须要根据不同的手机实现statusBarHeight和titleBarHeight

第一步:全局设置

把app.json中的window中的navigationStyle设置为custom官方文档链接

设置完之后发现导航栏变成了如下图所示,只剩下了右上角胶囊按钮

第二步:确定导航栏两部分的高度

(1)确定第一部分statusBarHeight的高度,这部分是手机用来展示时间,信号和手机电量的,我们可以从wx.getSystemInfo从获得

wx.getSystemInfo({
  success: function(res) {
    console.log(res.statusBarHeight)
  }
})

(2)第二部分titleBarHeight为小程序导航栏的高度,经过我查询无数文档和实践得知,在iPhone上titleBarHeight=44px,在安卓上titleBarHeight = 48px

(3)最后总结一下微信小程序的高度代码为

wx.getSystemInfo({
  success: function(res) {
    let titleBarHeight = 0
    if (res.model.indexOf('iPhone') !== -1) {
      titleBarHeight = 44
    } else {
      titleBarHeight = 48
    }
    that.setData({
      statusBarHeight: res.statusBarHeight,
      titleBarHeight: titleBarHeight
    });
  },
  failure() {
    that.setData({
      statusBarHeight: 0,
      titleBarHeight: 0
    });
  }
})

第三步:编写Navigation组件

(1)Navigation.js

const app = getApp();
Component({
  properties: {
    //小程序页面的标题
    title: {
      type: String,
      default: '默认标题'
    },
    //是否展示返回和主页按钮
    showIcon: {
      type: Boolean,
      default: true
    }
  },

  data: {
    statusBarHeight: 0,
    titleBarHeight: 0,
  },

  ready: function () {
    // 因为每个页面都需要用到这连个字段,所以放到全局对象中
    if (app.globalData && app.globalData.statusBarHeight && app.globalData.titleBarHeight) {
      this.setData({
        statusBarHeight: app.globalData.statusBarHeight,
        titleBarHeight: app.globalData.titleBarHeight
      });
    } else {
      let that = this
      wx.getSystemInfo({
        success: function(res) {
          if (!app.globalData) {
            app.globalData = {}
          }
          if (res.model.indexOf('iPhone') !== -1) {
            app.globalData.titleBarHeight = 44
          } else {
            app.globalData.titleBarHeight = 48
          }
          app.globalData.statusBarHeight = res.statusBarHeight
          that.setData({
            statusBarHeight: app.globalData.statusBarHeight,
            titleBarHeight: app.globalData.titleBarHeight
          });
        },
        failure() {
          that.setData({
            statusBarHeight: 0,
            titleBarHeight: 0
          });
        }
      })
    }
  },

  methods: {
    headerBack() {
      wx.navigateBack({
        delta: 1,
        fail(e) {
          wx.switchTab({
            url: '/pages/main/main'
          })
        }
      })
    },
    headerHome() {
      wx.switchTab({
        url: '/pages/main/main'
      })
    }
  }
})

(2) Navigation.wxml

<view style="height:{{titleBarHeight}}px;padding-top:{{statusBarHeight}}px">
  <view class="header" style="height:{{titleBarHeight}}px;padding-top:{{statusBarHeight}}px">
    <view wx:if="{{showIcon}}" class="title-bar">
      <view class="back" bindtap="headerBack"><image src="https://dn-testimage.qbox.me/Files/08/6b/086b8e19c7a5aa031dc4df31ca8b53ac2ed32212_644.png"></image></view>
      <view class="line"></view>
      <view class="home" bindtap="headerHome"><image src="https://dn-testimage.qbox.me/Files/fc/49/fc4958729bf1937667b68c78f495edeafe30f339_1030.png"></image></view>
    </view>
    <view class="header-title">{{title}}</view>
  </view>
</view>

css就不贴了,有点多,需要的朋友可以去的github上拿 点击地址

第四步:展示效果

                       iPhone X展示效果                                                     iPhone 7展示效果                                                      

               小米8展示效果

 

 

用我们公司的测试机基本上都试了一遍,基本上都能正常显示,别问我为什么样式和右边这么相似,因为我是叫公司设计给了我样式 

 

解决下拉刷新的问题

 

 图一为默认导航下的下拉刷新,显示正常,图二为自定义导航栏下的下拉刷新,显示异常,中间有一大块空白。

如果解决这个问题,我们自定义一个加载动画,藏在导航底下

(1)把app.json中的window设置为如下,这样加载动画就隐藏了,因为加载动画必须要设置window的backgroundTextStyle=black和backgroundColor=#F3F3F3才会显示如上图所示

window: {
  "navigationStyle": "custom",
  "backgroundTextStyle": "light",
  "navigationBarBackgroundColor": "#fff",
  "navigationBarTitleText": "ICY买手店",
  "navigationBarTextStyle": "black"
}

 

(2)修改Navigation.wxml

<view style="height:{{titleBarHeight}}px;padding-top:{{statusBarHeight}}px">
  <view class="header" style="height:{{titleBarHeight}}px;padding-top:{{statusBarHeight}}px">
    <view wx:if="{{showIcon}}" class="title-bar">
      <view class="back" bindtap="headerBack"><image src="https://dn-testimage.qbox.me/Files/08/6b/086b8e19c7a5aa031dc4df31ca8b53ac2ed32212_644.png"></image></view>
      <view class="line"></view>
      <view class="home" bindtap="headerHome"><image src="https://dn-testimage.qbox.me/Files/fc/49/fc4958729bf1937667b68c78f495edeafe30f339_1030.png"></image></view>
    </view>
    <view class="header-title">{{title}}</view>
  </view>
  <view class="loading-wrap"><image class="loading-gif" src="https://dn-testimage.qbox.me/Files/e0/35/e03562502eae6d5944bed747b7c21a3c2cce1ff8_1250.gif"></image></view>
</view>

效果如下图,加载动画我可能写的不太好看

 问题:这样做在iPhone上是能正常展示的,但是在安卓上还有一点小问题,自定义导航栏的标题和图标有一起滑动

注意点

(1)安卓手机下拉刷新还是会有一点点展示问题

(2)项目所有fixed的元素都需要改,top需要加上导航栏的高度

 目前哪些小程序在用自定义导航栏

我所知道的有 “bilibili”,"票圈长视频",我们公司的小程序也在计划用

 

posted @ 2018-12-11 18:11  面包大虾  阅读(6024)  评论(2编辑  收藏  举报