微信小程序自定义顶部导航栏navigationBar

野性酷女 2022-12-10 07:19 702阅读 0赞

自定义navigationBar怎么做?

去掉原生导航栏。

  1. 将需要自定义navigationBar页面的page.json的navigationBarTitleText去掉。
  2. 加上“navigationStyle”:”custom”,这样原生的导航栏就已经消失,甚至后退键也不会出现需要自定义。
  3. 另外,早在2016年微信已经开始适配沉浸式状态栏,目前几乎所有的机型里微信都是沉浸式状态栏,也就是说去掉原生导航栏的同时,整个屏幕已经成为可编程区域
  4. 文档:https://developers.weixin.qq.com/miniprogram/dev/extended/weui/navigation.html

计算navigationBarHeight。

  • 原生的胶囊按钮当然存在,那么下一步就需要你去定位出自定义的导航栏高度以及位置。
  • 对于不同的机型,对于不同的系统,状态栏以及胶囊按钮的位置都不确定,所以需要用到一定的计算,从而面对任何机型都可以从容判定。
  1. 使用wx.getSystemInfo()获取到statusBarHeight,这样就确定了导航栏最基本的距离屏幕上方的据里。
  2. 使用wx.getMenuButtonBoundingClientRect()获取到小程序的胶囊信息(注意这个api存在各种问题,在不同端表现不一致,后面会叙述这个api调用失败的处理情况),如下图,以下坐标信息以屏幕左上角为原点。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FzdGVyaWFW_size_16_color_FFFFFF_t_70
867a1fa0da90ee6c8aa9c4137ed82fd8.png

3.以下图为例,上面的红色框是statusBar,高度已知;下面的红色框是正文内容,夹在中间的就是求解之一navigationBarHeight;而黄色的是原生胶囊按钮也是在垂直居中位置,高度为胶囊按钮基于左上角的坐标信息已知,不难得出,navigationBarHeight = 蓝色框高度 × 2 + 胶囊按钮.height。(蓝色框高度 = 胶囊按钮.top - statusBarHeight

4.最后的计算公式为:navigationBarHeight = (胶囊按钮.top - statusBarHeight) × 2 + 胶囊按钮.height。navigationBar 距屏幕上方的距离即为navigationBarHeight

5.这种计算方法在各种机型以及安卓ios都适用。

6.针对”wx.getMenuButtonBoundingClientRect()“获取错误或者获取数据为0的极少数情况,只能够去模拟,对于android,一般navigationBarHeight为48px,而对于ios一般为40px,所有机型的胶囊按钮高度是32px笔者也是通过网上很多的文章和自测得出的,这种误差一般可以忽略。当然最理想的就是微信可以hold住所有机型,呵呵。最后提醒一下仅以真机为准,开发者工具的bug就更多不说了。

代码实现

  • 获取本机信息,一般写在App的onLaunch中。

    App.js

    // App.js

    onLaunch(){

    1. const { statusBarHeight, platform } = wx.getSystemInfoSync()
    2. const { top, height } = wx.getMenuButtonBoundingClientRect()
    3. // 状态栏高度
    4. wx.setStorageSync('statusBarHeight', statusBarHeight)
    5. // 胶囊按钮高度 一般是32 如果获取不到就使用32
    6. wx.setStorageSync('menuButtonHeight', height ? height : 32)
    7. // 判断胶囊按钮信息是否成功获取
    8. if (top && top !== 0 && height && height !== 0) {
    9. const navigationBarHeight = (top - statusBarHeight) * 2 + height
    10. // 导航栏高度
    11. wx.setStorageSync('navigationBarHeight', navigationBarHeight)
    12. } else {
    13. wx.setStorageSync(
    14. 'navigationBarHeight',
    15. platform === 'android' ? 48 : 40
    16. )
    17. }

    }

  • 笔者将这几个高度信息储存在stroage中,之后创建navigationBar自定义组件,在组件中将会运用到这些数据。

navigationBar.js

  1. // navigationBar.js
  2. ...
  3. data: {
  4. // 状态栏高度
  5. statusBarHeight: wx.getStorageSync('statusBarHeight') + 'px',
  6. // 导航栏高度
  7. navigationBarHeight: wx.getStorageSync('navigationBarHeight') + 'px',
  8. // 胶囊按钮高度
  9. menuButtonHeight: wx.getStorageSync('menuButtonHeight') + 'px',
  10. // 导航栏和状态栏高度
  11. navigationBarAndStatusBarHeight:
  12. wx.getStorageSync('statusBarHeight') +
  13. wx.getStorageSync('navigationBarHeight') +
  14. 'px'
  15. }
  16. ...
  • navigationBar.wxml中的布局就不多赘述,一般来说,导航栏使用fixed定位,里面再通过行内垂直居中的方式定位自定义的返回按钮,还有居中导航标题,以及字数过多显示省略号等。

navigationBar.wxml

  1. <!--navigationBar.wxml-->
  2. <view class="navigation-container" style="{
  3. {'height: ' + navigationBarAndStatusBarHeight}}">
  4. <!--空白来占位状态栏-->
  5. <view style="{
  6. {'height: ' + statusBarHeight}}"></view>
  7. <!--自定义导航栏-->
  8. <view class="navigation-bar" style="{
  9. {'height:' + navigationBarHeight}}">
  10. <view class="navigation-buttons" style="{
  11. {'height:' + menuButtonHeight}}">
  12. <image class="nav-img" src='/images/back.svg'/>
  13. ...其余自定义button
  14. </view>
  15. <view class="navigation-title" style="{
  16. {'line-height:' + navigationBarHeight}}">{
  17. {title}}</view>
  18. </view>
  19. </view>
  20. <!--空白占位fixed空出的位置-->
  21. <view style="{
  22. {'height: ' + navigationBarAndStatusBarHeight}}; background: #ffffff"></view>

navigationBar.wxss

  1. /* navigationBar.wxss */
  2. .navigation-container {
  3. position: fixed;
  4. width: 100%;
  5. z-index: 99;
  6. top: 0;
  7. left: 0;
  8. background-color: #ffffff;
  9. }
  10. .navigation-bar {
  11. position: relative;
  12. display: flex;
  13. flex-direction: row;
  14. align-items: center;
  15. }
  16. .navigation-buttons {
  17. display: flex;
  18. align-items: center;
  19. margin-left: 10px;
  20. border: 1px solid rgba(0, 0, 0, 0.05);
  21. box-sizing: border-box;
  22. border-radius: 15px;
  23. background-color: transparent;
  24. }
  25. .nav-img{
  26. height: 16px;
  27. width: 16px;
  28. }
  29. .navigation-title {
  30. position: absolute;
  31. left: 104px;
  32. right: 104px;
  33. text-align: center;
  34. font-size: 16px;
  35. font-weight: bold;
  36. color: #000000;
  37. overflow: hidden;
  38. text-overflow: ellipsis;
  39. white-space: nowrap;
  40. }

发表评论

表情:
评论列表 (有 0 条评论,702人围观)

还没有评论,来说两句吧...

相关阅读

    相关 程序定义导航

    看到有的微信小程序的页面左上角有了个“小房子”,可以返回首页,这是怎么做到的?其实这是微信开放的自定义的自定义导航栏来完成,但是最开始,对于一个页面很多的小程序,其实有点一言难