乐趣区

记一次小程序自定义导航栏及加载动画的解决方案

记一次自定义导航栏及加载动画的解决方案
主要逻辑就是动态获取设备的 statusBarHeight 和 titleBarHeight,来设置导航栏的高度和 paddingTop

ip6

ipx

loading
导航栏是一个组件,自定义组件通过 properties 获得 prop 参数的,组件还需要维护 statusBarHeight,titleBarHeight 和 navigatorHeight(实际没用到) 这三个 data
通过在小程序 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 系统。
因为判断是否为 IOS 系统才能够设置 titleBarHeight,iPhone 或 iPad 的这个值为 44,安卓的统一设置为 48 即可
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:
<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

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>
参考:

https://www.w3xue.com/exp/art…
https://juejin.im/post/5b7d5f…

退出移动版