记一次小程序自定义导航栏及加载动画的解决方案
主要逻辑就是动态获取设备的 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:
复制代码 B H { {title}} loading...
自定义导航栏的高度就是 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 文件:
复制代码
参考: