使用uni-app开发小程序经常会遇到胶囊按钮和标题之间融合的问题,因为这样可以大大提高页面的美观和整体性,那么接下来简单拆分步骤看下是如何实现的吧 😁
-
可以看到我们设置的标题是在默认标题栏之下的(这不是我们想要的效果 😭),正常状态栏和标题栏都会有个默认高度,这个默认高度是响应式的,应对不同的设备高度也会随之变化 🤔。
-
首先我们要到pages.json 👈路由文件中更改配置,将首页的navigationStyle属性的值改为custom,意思是取消默认的原生导航栏,通俗点说我们设置的标题就可以顶上去了 ✊
-
来看一下设置好完后的效果吧,是不是有那味了 😍😍😍
-
标题二字和搜索框是提前写好的,想着这两个元素该位置比较常用,所以就拿它们俩来举例(想添加其他元素也是同理的),文章的重点不是介绍它们的css样式哈,重点是如何实现在响应式(随设备而改变的)标题栏和状态栏中与胶囊按钮定位齐平的 📏
-
上面既然提到标题栏和状态栏是响应式的,所以标题和搜索框的定位位置是不能写死的 😂,那么我们怎样才能动态获取到标题栏和状态栏的位置数据呢,下面就要介绍两个nuiapp中的API了,第一个是
uni.getSysemlnfoSync()
,调用这个API可以获取到很多响应式的数据,需要关注的是statusBarHeight的值,该值表示当前设备下的状态栏高度(切记单位是px) 🤔第二个API是
uni.getMenuButtonBoundingClientRect()
,它可以获取胶囊按钮的多个数据,比如:胶囊按钮自身高度,底部、顶部到状态栏的距离等等(同样单位是px)🤔 -
这里标注了一张图小结一下,这样会更方便理解和记忆。一旦我们获取到 1️⃣状态栏高度 2️⃣胶囊按钮高度 3️⃣胶囊按钮上下的边距(上下边距是相同的距离),一切都会变得简单起来 🎉🎉🎉
-
基本思路分为三个区域 👇
- 1️⃣最上面的区域设置和标题栏一样的高度起到占位的作用;
- 2️⃣第二个区域求出胶囊按钮自身高度加上下边距,再从css中设置居中即可实现标题和搜索框与胶囊按钮齐平;
- 3️⃣第三个区域是把上面两个区域加起来,这是因为上面的区域都是固定定位会影响文档流,所以在文档流中占位,避免层级的遮挡
-
下面就用代码来演示具体是如何实现的吧 😳
<template> <view class="layout"> <view class="navbar"> <!-- 这里设置一个和状态栏一样高度的占位块 --> <view class="statusBar" :style="{height:statusBarHeight + 'px'}"></view> <!-- 通过计算得出的胶囊的横向居中位置 --> <view class="titleBar" :style="{height:titleBarHeight + 'px'}"> <view class="title">标题</view> <view class="search"> <uni-icons class="icon" type="search" color="#888" size="18"></uni-icons> <text class="text">搜索</text> </view> </view> </view> <!-- 因为使用了固定定位所以会跳出文档流挡住,这里设置一个状态栏加标题栏的高度即可错开,正常显示其他内容 --> <view class="fill" :style="{height:statusBarHeight + titleBarHeight + 'px'}"></view> </view> </template> <script setup> import { ref } from 'vue'; //获取到状态栏高度 let SYSTEM_INFO = uni.getSystemInfoSync() let statusBarHeight = ref(SYSTEM_INFO.statusBarHeight) //获取到胶囊按钮自身高度+上下两个边距高度,再从css中设置居中即可实现标题和搜索框与胶囊按钮齐平 let {top, height} = uni.getMenuButtonBoundingClientRect() let titleBarHeight = height + (top - statusBarHeight.value) * 2 </script> <style lang="scss" scoped> .layout{ .navbar{ position: fixed; //采用固定定位 top: 0; left: 0; width: 100%; z-index: 10; background: linear-gradient(to bottom, transparent, #fff 400rpx), linear-gradient(to right, #beecd8, #F4E2D8); .titleBar{ padding: 0 30rpx ; display: flex; align-items: center; .title{ font-size: 22px; font-weight: 700; color: #000; } .search{ width: 220rpx; height: 50rpx; border-radius: 60rpx; background: rgba(255, 255, 255, 0.4); border: 1px solid #fff; margin-left: 30rpx; color:#999; font-size: 28rpx; display: flex; align-items: center; .icon{ margin-left: 5rpx; } .text{ padding-left: 10rpx; } } } } .fill{} } </style>
表达能力有限 😭,如有不明白的地方随时私信解答哈📨,创作不易喜欢的同学别忘了点点赞哦 😘😘😘