最近在做小程序项目,需要用到自定义navigationBar,之前用过colorUI等组件库的navigationBar组件,但是现在想自己写一个,所以有了今天的小记

在做navigationBar之前我们先了解一下navigationBar是什么 ?

微信小程序一般来说有两个bar,一个导航栏,一个tabbar(小程序下方一排切换按钮),实现下方自定义tabbar的方法一般来说较为简单,现在着重叙述上方自定义导航栏的实现。

为什么要自定义navigationBar?

原生导航栏的限制

  • 除了胶囊按钮以外,原生导航栏只会出现返回按钮和当用户打开的小程序最底层页面是非首页时,默认展示的“返回首页”按钮 。
  • 原生导航栏的标题文字的颜色只有黑白。
  • 布局无法改变,不能做定制。

产品需求

  • 如果说原生导航栏的限制还不足以让你加入自定义导航栏,那么产品需求绝对是更大的推动力。

  • 自定义导航栏除了不能自定义胶囊按钮以外,其他的范围都是程序员的掌控范围,所以使用自定义导航栏无疑可以满足产品的各种需求。

实际的开发过程中我们会用到以下方法:

  • wx.getSystemInfo()  用于获取系统信息(如设备品牌、设备型号、屏幕大小等,具体参数在文章末尾)
  • wx.getMenuButtonBoundingClientRect()  用于获取小程序的胶囊信息

了解了自定义NAVIGATIONBAR之后我们需要知道怎么做?

  1. 去掉原生导航栏。

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

2.计算navigationBar高度。

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

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

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

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

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

代码实现

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

app.js

//计算导航栏高度const { statusBarHeight, platform } = wx.getSystemInfoSync()const { top, height } = wx.getMenuButtonBoundingClientRect()// 状态栏高度wx.setStorageSync('statusBarHeight', statusBarHeight)// 胶囊按钮高度 一般是32 如果获取不到就使用32wx.setStorageSync('menuButtonHeight', height ? height : 32)// 判断胶囊按钮信息是否成功获取if (top && top !== 0 && height && height !== 0) {
//获取成功进行计算const navigationBarHeight = (top - statusBarHeight) * 2 + height// 导航栏高度wx.setStorageSync('navigationBarHeight', navigationBarHeight)} else {
//获取失败使用默认的高度wx.setStorageSync('navigationBarHeight',platform === 'android' ? 48 : 40)}
  • 笔者将这几个高度信息储存在stroage中(也可以存到全局变量中),之后创建navigationBar自定义组件,在组件中将会运用到这些数据。

navigationBar.js

    // 状态栏高度statusBarHeight: wx.getStorageSync('statusBarHeight') + 'px',// 导航栏高度navigationBarHeight: wx.getStorageSync('navigationBarHeight') + 'px',// 胶囊按钮高度menuButtonHeight: wx.getStorageSync('menuButtonHeight') + 'px',// 导航栏和状态栏高度navigationBarAndStatusBarHeight: wx.getStorageSync('statusBarHeight') +wx.getStorageSync('navigationBarHeight') +'px',//标题title: '积分游戏'

navigationBar.wxml

<view class="navigation-container" style="{{'height: ' + navigationBarAndStatusBarHeight}}"><!--空白来占位状态栏--><view style="{{'height: ' + statusBarHeight}}"></view><!--自定义导航栏--><view class="navigation-bar" style="{{'height:' + navigationBarHeight}}"><!-- 这里就是导航栏 你可以将你想要的样式放到这里--><view class="navigation-buttons" style="{{'height:' + menuButtonHeight}}"><image class="nav-img" src='/images/back.svg'/>...其余自定义button</view><view class="navigation-title" style="{{'line-height:' + navigationBarHeight}}">{{title}}</view></view>
</view>
<!--空白占位fixed空出的位置-->
<view style="{{'height: ' + navigationBarAndStatusBarHeight}}; background: #ffffff"></view>

navigationBar.wxss

/* navigationBar.wxss */
.navigation-container {position: fixed;width: 100%;z-index: 99;top: 0;left: 0;background-color: #ffffff;
}
.navigation-bar {position: relative;display: flex;flex-direction: row;align-items: center;
}
.navigation-buttons {display: flex;align-items: center;margin-left: 20rpx;border: 1px solid rgba(0, 0, 0, 0.05);box-sizing: border-box;border-radius: 30rpx;background-color: transparent;
}
.nav-img{height: 32rpx;width: 32rpx;
}
.navigation-title {position: absolute;left: 208rpx;right: 208rpx;text-align: center;font-size: 32rpx;font-weight: bold;color: #000000;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}

总结

  • 自定义导航栏核心在于导航栏的高度定位,这样才能准确定位自定义的返回按钮以及其他按钮的位置,与原生胶囊保持一致。至于wxml的布局方法多种多样,上面只是列出了笔者的一种写法。
  • 学习小程序,自定义导航栏是很重要的技能,其间的逻辑并不复杂,还是和学习前端一样,需要非常细心耐心,才能做好细节工作

wx.getSystemInfo()获取到的参数

微信小程序自定义navigationBar、自定义标题栏相关推荐

  1. 微信小程序scroll-view实现自定义刷新

    微信小程序scroll-view实现自定义刷新@TOC 先说原生页面级的刷新 通常我们可以利用微信小程序的onPullDownRefresh函数(下拉刷新监听函数)和onReachBottom函数(上 ...

  2. 微信小程序之callout自定义气泡

    最近闲着踩踩地图的坑,一脚下去差点没从坑里爬起来,然后由于某个原因,去研究了微信小程序里面地图callout 这个属性 callout呢,是在标记的点上面显示 一个 气泡,作为提示用 最后展示下 效果 ...

  3. 微信小程序用vant自定义tabbar页面并跳转相应页面

    0.前置安装 步骤一 安装 vant 组件库 npm i @vant/weapp -S --production 下载完后要npm构建才能使用 步骤二 修改 app.json 将 app.json 中 ...

  4. 微信小程序底部实现自定义动态Tabbar

    多图警告!!! 最近在工作中遇到这样一个需求:微信小程序底部的Tab需要通过判断登录人的角色动态进行改变,想要实现这个功能依靠小程序原生的Tabbar是不可能实现的了,所以研究了一下自定义Tab,这里 ...

  5. 微信小程序顶部透明状态标题栏搜索栏与胶囊对齐

    微信小程序顶部透明状态标题栏搜索栏LOGO与胶囊对齐 效果如下 App.js wx.getSystemInfo({success: res => {console.log(res)let cus ...

  6. 微信小程序 - 进阶(自定义组件、promis化、mobx、分包、自定义tabBar)

    文章目录 一.自定义组件 1.创建组件 2.引用组件 3.组件和页面区别 4.组件样式 5.data.methods.properties 6.小程序的 data 和 properties 区别 7. ...

  7. Taro编译微信小程序实现顶部自定义导航栏

    [需求] 使用taro开发微信小程序的过程中,涉及到小程序的需要自定义顶部导航栏(导航栏渐变色),微信小程序中只能够设置固定的颜色,渐变颜色以及添加其他按钮的操作就不能够通过小程序自带的api来实现 ...

  8. 【微信小程序】使用自定义字体

    微信小程序使用自定义字体 文章目录 微信小程序使用自定义字体 1. 微信小程序默认支持的字体 2. 自定义字体获取 3. 文字提取和字体ttf文件压缩 4. 字体转Base64格式 5. 字体应用到小 ...

  9. 微信小程序使用weui自定义底部导航栏,切换不同页面显示不同tabbar

    在一个微信小程序中想要用到两种不同的tabbar样式,可以使用微信小程序自带插件tabbar 首先在页面json文件中引入 tabbar {"navigationBarTitleText&q ...

  10. 微信小程序轮播中的current_微信小程序开发之自定义轮播图实例

    轮播图是大部分应用的一个常用的功能,常用于广告投放.产品展示.活动展示等等. 漂亮的轮播图效果可以吸引用户的点击,达到推广产品的作用. 废话少说,下面开始动手. 业务需求: 5个图片轮番播放,可以左右 ...

最新文章

  1. 启动targetcli时遭遇ImportError: cannot import name ALUATargetPortGroup故障
  2. FW: HTTP错误500显示具体的出错信息的方法
  3. 云计算与虚拟化以及IaaS, PaaS和SaaS
  4. kdj值应用口诀_KDJ买卖绝学!记住这些操作 精准判断quot;顶部和底部quot; 让你远离亏损...
  5. 【CV】YOLO算法最全综述:从YOLOv1到YOLOv5
  6. JS跳转手机QQ的聊天页面
  7. linux数据泵导入command not found_MySQL:数据库结构优化、高可用架构设计、数据库索引优化...
  8. pythonic code_Pythonic Code (Part III)
  9. java 28181协议_WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台
  10. 力扣题目算法分类【持续更新】
  11. 现代控制理论电子版_SANXINB01开发板verilog教程V3电子版
  12. java 连线题_java练习题
  13. DataFrame 修改列名
  14. Android 常用开发工具以及Mac常用软件
  15. 微信、QQ上线国产系统UOS:界面曝光
  16. Vue多个元素的过渡
  17. 深圳计算机学校排名2015,深圳学校排行榜Top20!深圳人挤破头都想上的小学中学大学...
  18. 贝尔商道赚钱思维36道第08道:聪公移山
  19. Windows11 右键卡顿
  20. SpringSecurity原理:探究SpringSecurity运作流程

热门文章

  1. 2022年10月16日 8点 程序爱生活 纳指和恒指反弹的概率还在,但是反弹做空为主。
  2. 与微信双向互通的企业即时通讯软件AM8
  3. 如何在电脑桌面添加便签,从此告别纸质便签
  4. 多功能视频处理器——MS1824
  5. Loj 538 递推数列
  6. 移动设备软件开发-3
  7. 一篇文章带你读懂Python的魔法方法
  8. 老子的软件之道 - 道篇 32 知止不殆
  9. windows下搭建Git服务器
  10. java strlen_strlen函数详解