900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 微信小程序自定义导航栏组件(完美适配所有手机) 可自定义实现任何你想要的功能

微信小程序自定义导航栏组件(完美适配所有手机) 可自定义实现任何你想要的功能

时间:2020-06-28 20:14:06

相关推荐

微信小程序自定义导航栏组件(完美适配所有手机) 可自定义实现任何你想要的功能

背景

在做小程序时,关于默认导航栏,我们遇到了以下的问题:

Android、IOS 手机对于页面 title 的展示不一致,安卓 title 的显示不居中页面的 title 只支持纯文本级别的样式控制,不能够做更丰富的 title 效果左上角的事件无法监听、定制路由导航单一,只能够返回上一页,深层级页面的返回不够友好

探索

小程序自定义导航栏已开放许久>>了解一下,相信不少小伙伴已使用过这个功能,同时不少小伙伴也会发现一些坑:

机型多如牛毛:自定义导航栏高度在不同机型始终无法达到视觉上的统一导航栏中内容怎么都不垂直居中对齐,更别说适配所有手机调皮的胶囊按钮:导航栏元素(文字,图标等)怎么也对不齐那该死的胶囊按钮各种尺寸的全面屏,奇怪的刘海屏,简直要抓狂

一探究竟

为了搞明白原理,我先去翻了官方文档,>>飞机,点过去是不是很惊喜,很意外,通篇大文尽然只有最下方的一张图片与这个问题有关,并且啥也看不清,汗汗汗…

我特意找了一张图片来

分析上图,我得到如下信息:

Android 跟 iOS 有差异,表现在顶部到胶囊按钮之间的距离差了 6pt胶囊按钮高度为 32pt, iOS 和 Android 一致

动手分析

我们写一个状态栏,通过 wx.getSystemInfoSync().statusBarHeight 设置高度

Android:

iOS:

可以看出,iOS 胶囊按钮与状态栏之间距离为:4px, Android 为 8px,是不是所有手机都是这种情况呢?

答案是:苹果手机确实都是 4px,安卓大部分都是 7 和 8 也会有其他的情况(可以自己打印 getSystemInfo 验证)如何快速便捷算出这个高度,请接着往下看

如何计算

导航栏分为状态栏和标题栏,只要能算出每台手机的导航栏高度问题就迎刃而解

导航栏高度 = 胶囊按钮高度 + 状态栏到胶囊按钮间距 * 2 + 状态栏高度

注:由于胶囊按钮是原生组件,为表现一致,其单位在各种手机中都为 px,所以我们自定义导航栏的单位都必需是 px(切记不能用 rpx),才能完美适配。

解决问题

现在我们明白了原理,可以利用胶囊按钮的位置信息和 statusBarHeight 高度动态计算导航栏的高度,贴一个实现此功能最重要的方法

let systemInfo = wx.getSystemInfoSync();let rect = wx.getMenuButtonBoundingClientRect ? wx.getMenuButtonBoundingClientRect() : null; //胶囊按钮位置信息wx.getMenuButtonBoundingClientRect();let navBarHeight = (function() {//导航栏高度let gap = rect.top - systemInfo.statusBarHeight; //动态计算每台手机状态栏到胶囊按钮间距return 2 * gap + rect.height;})();

gap 信息就是不同的手机其状态栏到胶囊按钮间距,具体更多代码实现和使用 demo 请移步下方代码仓库,代码中还会有输入框文字跳动解决办法,安卓手机输入框文字飞出解决办法,左侧按钮边框太粗解决办法等等

胶囊信息报错和获取不到

问题就在于 getMenuButtonBoundingClientRect 这个方法,在某些机子和环境下会报错或者获取不到,对于此种情况完美可以模拟一个胶囊位置出来

try {rect = Taro.getMenuButtonBoundingClientRect ? Taro.getMenuButtonBoundingClientRect() : null;if (rect === null) {throw 'getMenuButtonBoundingClientRect error';}//取值为0的情况if (!rect.width) {throw 'getMenuButtonBoundingClientRect error';}} catch (error) {let gap = ''; //胶囊按钮上下间距 使导航内容居中let width = 96; //胶囊的宽度,android大部分96,ios为88if (systemInfo.platform === 'android') {gap = 8;width = 96;} else if (systemInfo.platform === 'devtools') {if (ios) {gap = 5.5; //开发工具中ios手机} else {gap = 7.5; //开发工具中android和其他手机}} else {gap = 4;width = 88;}if (!systemInfo.statusBarHeight) {//开启wifi的情况下修复statusBarHeight值获取不到systemInfo.statusBarHeight = systemInfo.screenHeight - systemInfo.windowHeight - 20;}rect = {//获取不到胶囊信息就自定义重置一个bottom: systemInfo.statusBarHeight + gap + 32,height: 32,left: systemInfo.windowWidth - width - 10,right: systemInfo.windowWidth - 10,top: systemInfo.statusBarHeight + gap,width: width};console.log('error', error);console.log('rect', rect);}

以上代码主要是借鉴了拼多多的默认值写法,android 机子中 gap 值大部分为 8,ios 都为 4,开发工具中 ios 为 5.5,android 为 7.5,这样处理之后自己模拟一个胶囊按钮的位置,这样在获取不到胶囊信息的情况下,可保证绝大多数机子完美显示导航头

吐槽

这么重要的问题,官方尽然没有提供解决方案…竟然提供了一张看不清的图片???

网上有很多 ios 设置 44,android 设置 48,还有根据不同的手机型号设置不同高度,通过长时间的开发和尝试,本人发现以上方案并不完美,并且 bug 很多

代码库

Taro 组件gitHub 地址详细用法请参考 README原生组件 npm 构建版本gitHub 地址详细用法请参考 README原生组件简易版gitHub 地址详细用法请参考 README由于本人精力有限,目前只计划发布维护好这 2 种组件,其他组件请自行修改代码,有问题请联系

备注

上方 2 种组件在最下方 30 多款手机测试情况表现良好iPhone 手机打电话和开热点导致导航栏样式错乱,问题已经解决啦,请去 demo 里测试,这里特别感谢 moments 网友提出的问题本文章并无任何商业性质,如有侵权请联系本人修改或删除文章少量部分内容是本人查询搜集而来如有问题可以下方留言讨论,微信 zhijunxh

比较

斗鱼:

虎牙:

微博:

酷狗:

知乎:

知乎是这里边做的最好的,但是我个人认为有几个可以优化的小问题

打电话或者开启热点导致样式错落,这也是大部门小程序的问题导航栏下边距太小,看起来不舒服搜索框距离 2 侧按钮组距离不对等自定义返回和 home 按钮中的竖线颜色重了,并且感觉太粗

如果您看到了此篇文章,请赶快修改自己的代码,并运用在实践中吧

扫码体验我的小程序:

创作不易,如果对你有帮助,请移步 Taro 组件gitHub原生组件gitHub给个星星 star✨✨ 谢谢

测试信息

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。