评论

小程序自定义导航栏的开发原理及编码思路实践 (附带可直接使用的自定义导航栏组件)

介绍了微信小程序自定义导航栏的创建原理,思路以及方法实践,并提供了已经封装好的自定义导航栏自定义组件,以供读者使用。

1.引言

在小程序应用开发过程中,导航栏作为页面标题性的存在,不但起到了用户指引路由的作用,更是在应用功能较为完善和复杂的情况下,起到了进一步的功能性作用,小程序的原生导航栏如下:

显然,原生的导航栏除了能够提供标题,返回键等功能外,其他功能到目前为止并没有浮出水面。而为了定制符合我们自己开发要求的导航栏,此时,我们就需要对导航栏进行自定义的设计开发。自定义开发过导航栏效果如图:

2.原理及思路

(1)原理

首先我们要知道几个概念:状态栏导航栏导航栏胶囊导航栏胶囊在导航栏中的上下边距

状态栏:是指通常手机顶部显示手机运营商,手机信号,手机电量等等信息的最顶层一栏。

导航栏:是指在小程序中显示胶囊按钮,返回键,标题的一栏。

导航栏胶囊:是指小程序中导航栏右部出现的胶囊状按钮,小程序中会一直置顶显示,在不同的机型中,胶囊的高度是固定的,目前均为32px

导航栏胶囊在导航栏中的上下边距:胶囊按钮在导航中不是上下撑满的,是上下居中布局的,所以存在上下相等的边距。

效果说明图如下:

在小程序开发中,我们可以获取以下数据:

胶囊的布局位置及尺寸信息:(详情点击查看https://developers.weixin.qq.com/miniprogram/dev/api/ui/menu/wx.getMenuButtonBoundingClientRect.html

wx.getMenuButtonBoundingClientRect()

(2)思路

原理我们都已经介绍过了,现在需要我们想一想设计的思路。

最常规的思路就是来个和导航栏一样宽度,一样高度的页面容器绝对定位覆盖在导航栏上面就可以了。然后在这个覆盖容器里面进行自定义发挥就可以了,保准自定义的内容和胶囊对齐的准准的,不会有任何问题。

那么,该怎么获取导航栏的高度和定位信息呢(宽度肯定是满宽,100vw)。

从上面的效果演示图我们可以知道,导航栏的高度是等于 胶囊高度+胶囊上边距 * 2 的,这个应该不难理解,胶囊高度上文已经提过,是固定的:32px,所以,我们只要再求出胶囊的上边距就可以了。上边距我们可以通过由 wx.getMenuButtonBoundingClientRect() 获取的胶囊距顶部的距离减去状态栏高度获取。从而计算出状态栏的高速。而后就可以实现我们一开始的思路,将一高度与导航栏相同,绝对定位在距屏幕顶部一个状态栏高度的距离便可以实现完全的导航栏精确覆盖。

3.代码实现


      //胶囊上边框距顶部距离
      const capsuleTop = wx.getMenuButtonBoundingClientRect().top;
      //状态栏高度
      const statusBarHeight = wx.getSystemInfoSync().statusBarHeight;
      //药囊上边距状态栏下边的距离,即药囊在导航内容栏中的上下边距
      const capsuleGap = capsuleTop - statusBarHeight;
      //导航内容栏的高度动态计算
      const navContentHeight = capsuleGap * 2 + this.data.capsuleHeight;


4.注意事项。

(1)在定位好的自定义导航栏里编写内容时,不要与胶囊重合,否则会被胶囊覆盖,此时需要计算可使用区域的宽度,在计算宽度时,为了达到各机型效果的一致,需要根据当前模拟机型的宽度进行px对rpx的换算,才能使自定义组件中的内容的宽度在各个机型中效果一致。

(2)本文所述自定义导航栏的创建方法必须基于该自定义导航栏针对页面fixed绝对定位的基础上才可以。

5.结语

在编写自定义导航栏之前也查了很多材料,感觉都不太准,自己借鉴着摸索了一套自己的方法,请大家评判一番,我已将该自定义导航栏封装成了微信小程序自定义组件,插之即用,以供大家提高生产效率:

NPM安装:https://www.npmjs.com/package/russell-weapp

github:https://github.com/RussellCao824/russell-weapp


最后一次编辑于  2020-06-07  
点赞 2
收藏
评论

2 个评论

  • November.
    November.
    2020-09-25

    “导航栏的高度是等于  胶囊高度+胶囊上边距 * 2  的”

    这是谁告诉你的,自己去刘海屏的iphone上测试一下。用自己写的menu.bottom + menu.top - statusHeight高度的导航栏和系统自带的导航栏比对一下高度,明显矮了一点。

    2020-09-25
    赞同 2
    回复 1
    • CZ
      CZ
      2020-10-31
      您好,没有搞明白您说的:menu.bottom + menu.top - statusHeight这个是什么的高度,我看您写的这个计算式子应该是导航栏+状态栏的高度和。
      2020-10-31
      回复
  • 白俊鹏
    白俊鹏
    2020-07-09

    你好,这个可使用区域的宽度要怎么计算呢?

    2020-07-09
    赞同
    回复 6
    • CZ
      CZ
      2020-07-09
      您好,意思就是,胶囊的位置以及胶囊的右边,肯定不能有内容,否则会重合。所以就必须把内容放在胶囊的左边,这个区域就是可用区域,比如说你要放个搜索框,在设置搜索框的宽度时,一般会根据搜索框的左右边距来确定搜索框的位置和宽度,因为胶囊通过wx.getMenuButtonBoundingClientRect()计算出来的所有位置信息都是px为单位的,所以,为了使在不同机型中样式都一致,就需要把所有计算过程中的宽度都根据你当前的测试机型转化为rpx单位。屏幕整个宽度为750rpx,根据这个比例进行换算即可。
      2020-07-09
      回复
    • 白俊鹏
      白俊鹏
      2020-07-09回复CZ
      胶囊的宽度和右边距是不是在不同机型里面都是固定的呀?
      2020-07-09
      回复
    • 白俊鹏
      白俊鹏
      2020-07-09回复CZ
      或者,如果我把搜索框宽度写个比如:500rpx,在某些机型下面他会跑到胶囊下面去吗?
      2020-07-09
      回复
    • CZ
      CZ
      2020-07-09回复白俊鹏
      宽度和右边距都不是固定的,你可以自己使用wx.getMenuButtonBoundingClientRect()这个api测试一下,至于你说的搜索框的宽度定位,你可以不通过设置搜索框两边的边距,然后中间的部分自然就是搜索框的宽度,单位只要都是rpx,任何机型就样式一致
      2020-07-09
      回复
    • 白俊鹏
      白俊鹏
      2020-07-09回复CZ
      这句话没看太懂,,,
      2020-07-09
      回复
    查看更多(1)
登录 后发表内容