百分百兼容的小程序 nav-bar 实现思路,了解一下?

1,797 阅读4分钟

先说结论:

别折腾了,直接用uni 的轮子就行,二开也可以,我这个方法能实现,但是安卓机总会有获取不到胶囊高度的情况,偶现。。

1、背景:

最近使用uni-app开发多端使用的小程序(微信、支付宝、H5), 开发过程中需要做一个nav组件

最先想到的肯定是用别人造好的轮子,比如uni-nav-bar这个组件,但是实测使用发现,不同手机型号

(ios/安卓)都会有一些兼容问题,而且使用也会有一些限制,不够舒服,所以就想办法自己做了个简单的

header , 这里写一下思路,思路有了,其他的按需求开发即可

🍕首先大概解释一下nav的基本内容

nav的高度一般是通过getSystemInfo获取系统信息,得到titleBarHeightstatusBarHeight,然后相加得到最终高度 , 但是这种方式会有一些兼容问题,后续会细说

image.png

DEMO


uni.getSystemInfo(() => {
	const systemInfo = app.globalData.systemInfo;
	this.systemInfo = systemInfo;
        
        /**
        *@statusBarHeight: 一般为25px
        *@titleBarHeight :一般为44px
        */
        
	// #ifdef MP-ALIPAY
	this.barHeight = systemInfo.titleBarHeight + systemInfo.statusBarHeight || 69;
	this.searchHeight = systemInfo.titleBarHeight || 44;
	// #endif

	// #ifdef MP-WEIXIN
	this.barHeight = systemInfo.safeArea.top + systemInfo.statusBarHeight || 69;
	this.searchHeight = systemInfo.statusBarHeight || 44;
	//  #endif
});
                        

2、需求:

如下图 , 内容区域不管在什么设备下都要和胶囊按钮 同高 或在一条基线上,至少不能有很明显的偏差。。。

image.png

3、遇到的问题:

首先说明一下,这里我就大概看了一下,没有深入研究该组件,可能是我用法不对的原因

使用uni-nav-bar过程遇到的几个问题:

1、左侧位置较小(如图圈起来的部分)

  • 这个比较小,可以改源码样式处理

    image.png

2、statusBar不同机型高度差很多,有的机型干脆获取不到

最终造成内容区域胶囊按钮位置偏差 ,如图:

  • 正常情况

    image.png

  • (nexus、安卓机器等)

    image.png

4、实现思路:

1、获取右侧胶囊的位置信息,把内容区域的高度调整到和胶囊按钮同样的位置即可

2、状态栏高度则BFC布局高度自适应,不再设置固定高度

3、胶囊下面填充区域直接写死,我这边固定10px , 按需设置即可

5、具体实现:

5.1. 获取胶囊按钮高度位置 , 并设置nav的高度

✨✨✨✨最重要的步骤✨✨✨✨🐱‍👤🐱‍👤🐱‍👤🐱‍👤🐱‍👤🐱‍👤🐱‍👤

getNavHeight() {
	// #ifndef H5
	const res = wx.getMenuButtonBoundingClientRect();
	const statusHeight = res?.top || 0; //胶囊距离顶部
	const navHeight = res.height; //胶囊高度
	this.statusBarHeight = statusHeight;
	this.navHeight = navHeight + statusHeight + 10; //加10是因为样式需要,后续做内边距
	// #endif

	// #ifdef H5
	this.statusBarHeight = 14;
	this.navHeight = 44;
	// #endif
}

5.2. 布局大概如下

image.png

5.3. html布局

这里只是做一个演示,实际最终要按需求来写


<view class="nav_header" :style="{ height: navHeight + 'px' }">
        <!-- 状态栏 -->
	<view class="status-bar"/>
        <!-- 内容区域 -->
	<view class="content">
            <!-- logo -->
            <image class="nav_icon" src="@/static/test-logo.png" mode="aspectFit" />
             <!-- 跳转按钮 -->
            <navigator
                    class="search_link"
                    open-type="navigate"
                    url="/pages/search/index?source=首页"
                    hover-class="none"
            >
		<image class="search_icon" src="@/static/images/search.png" mode="aspectFit" />
			搜索
            </navigator>
        </view>
</view>

5.4. 样式处理

布局及需求如下

  • nav_header
    • status_bar(高度自适应,自动填满剩下区域)
    • content (高度固定 or 和胶囊按钮在同一条线 )

其实上面算一个比较经典的bfc,常见的bfc左侧宽度固定,右侧自适应,而这里换成了下面的内容区域高度固定,顶部状态栏高度自适应😅


.nav_header {
		position: fixed;
		width: 100%;
		top: 0;
		left: 0;
		z-index: 10;
		overflow: hidden;
		height: auto;
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		box-sizing: border-box;
		background-color: green;

		/* #ifndef H5*/
		padding-bottom: 10px;
		/* #endif*/

		/* #ifdef H5*/
		padding-bottom: 8px;
		/* #endif*/

		.status-bar {
			width: 100%;
			flex: 1;
			background-color: cornflowerblue;
		}

		.content {
			display: flex;
			background: #ff602a;
			width: 100%;
			height: 50rpx;
			z-index: 10;

			.nav_icon {
				color: #fff;
				width: 204rpx;
				height: 100%;
			}

			.search_link {
				margin-left: 20rpx;
				box-sizing: border-box;
				height: 100%;
				align-items: center;
				border-radius: 32rpx;
				background: rgba(255, 255, 255, 0.56);
				color: #ffffff;
				padding: 0 20rpx;
				margin-left: 60rpx;
				width: 300rpx;

				.search_icon {
					width: 36rpx;
					height: 36rpx;
					margin-right: 16rpx;
				}
			}
		}
	}

6、效果

6.1.微信 :

image.png

6.2.支付宝:

image.png

7、最终效果:

经真机测试,这种方法做出来的nav不管是安卓还是ios兼容都还是蛮ok的,也确实能解决我碰到的问题, 当然这里只是做了一个非常简单的header ,如果需要的话可以封装成通用header,类似uni-nav-bar一样通过slot的方式自定义header

  • 微信开发者工具

    123.gif

  • 支付宝开发者工具

    345.gif

写在最后😬🤯😬🧐🤓:

这里只是提供一个解决思路,如果大家有更好的方法或者好用的轮子,请务必留在评论区,谁都别拦着我要跪着学🤩🤩!