一、需求:
我们有一个uniapp开发的H5,需要嵌入第三方的APP中,但是状态栏文字(如时间、信号、电池)遮挡导航栏内容,如图所示
需要做到:
1.导航栏始终处于页面最顶端
2.导航栏不能遮挡状态栏
如图所示
二、解决方式
1.引入安全区概念,会自动获取状态栏高度
javascript
onLoad() {
uni.getSystemInfo({
success: (result) => {
//获取安全区距离并存入本地
uni.setStorageSync('statusBarHeight', result.statusBarHeight)
}
})
},
2.导航栏高度=本身高度(40px)+安全区高度。 再设置padding-top=安全区高度。这样导航栏始终处于状态栏之下
javascript
<!-- 安全区域占位 -->
<view class="navbar-container" :style="{
height: (statusBarHeight + 40) + 'px', // 安全区高度 + 导航栏高度
paddingTop: statusBarHeight + 'px' // 导航栏内容避开安全区
}">
<view class="navbarBox">
<u-icon name="arrow-left" color="#2979ff" size="28" @click="goBack"></u-icon>
<p>短信与任务</p>
<view class="placeholder"></view>
</view>
</view>
3.设置导航栏固定位置
javascript
.navbar-container {
position: fixed; // 关键:固定定位,不随滚动移动
top: 0;
left: 0;
right: 0;
background: rgb(148, 194, 247); // 和页面背景一致,避免穿透
z-index: 999; // 确保导航栏在最上层,不被内容覆盖
box-sizing: border-box;
padding: 0 10px; // 和页面容器的padding对齐,避免导航栏内容偏移
}
4.将滚动区域设置高度
javascript
<view class="content-container" :style="{
height: `calc(100vh - ${statusBarHeight + 40}px)`, // 动态减去导航栏总高度
marginTop: `${statusBarHeight + 40}px` // 顶部间距=导航栏总高度,双重保险
}">
<u-list @scrolltolower="scrolltolower">
<u-list-item v-for="(item, index) in indexList" :key="index">
<u-cell :title="`列表长度-${index + 1}`">
<u-avatar slot="icon" shape="square" size="35" :src="item.url"
customStyle="margin: -3px 5px -3px 0"></u-avatar>
</u-cell>
</u-list-item>
</u-list>
</view>
三、提示+完整代码
1.提示:源码使用了Uview组件(地址),可删除或自行引入
2.源码
javascript
<template>
<view class="u-page">
<!-- 安全区域占位 -->
<view class="navbar-container" :style="{
height: (statusBarHeight + 40) + 'px', // 安全区高度 + 导航栏高度
paddingTop: statusBarHeight + 'px' // 导航栏内容避开安全区
}">
<view class="navbarBox">
<u-icon name="arrow-left" color="#2979ff" size="28" @click="goBack"></u-icon>
<p>短信与任务</p>
<view class="placeholder"></view>
</view>
</view>
<view class="content-container" :style="{
height: `calc(100vh - ${statusBarHeight + 40}px)`, // 动态减去导航栏总高度
marginTop: `${statusBarHeight + 40}px` // 顶部间距=导航栏总高度,双重保险
}">
<u-list @scrolltolower="scrolltolower">
<u-list-item v-for="(item, index) in indexList" :key="index">
<u-cell :title="`列表长度-${index + 1}`">
<u-avatar slot="icon" shape="square" size="35" :src="item.url"
customStyle="margin: -3px 5px -3px 0"></u-avatar>
</u-cell>
</u-list-item>
</u-list>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//安全区距离
statusBarHeight: JSON.parse(uni.getStorageSync("statusBarHeight")),
indexList: [],
urls: [
"https://uviewui.com/album/1.jpg",
"https://uviewui.com/album/2.jpg",
"https://uviewui.com/album/3.jpg",
"https://uviewui.com/album/4.jpg",
"https://uviewui.com/album/5.jpg",
"https://uviewui.com/album/6.jpg",
"https://uviewui.com/album/7.jpg",
"https://uviewui.com/album/8.jpg",
"https://uviewui.com/album/9.jpg",
"https://uviewui.com/album/10.jpg",
],
}
},
onLoad() {
uni.getSystemInfo({
success: (result) => {
uni.setStorageSync('statusBarHeight', result.statusBarHeight)
console.log(JSON.parse(uni.getStorageSync("statusBarHeight")), 666);
}
})
this.loadmore();
},
methods: {
scrolltolower() {
this.loadmore();
},
loadmore() {
for (let i = 0; i < 30; i++) {
this.indexList.push({
url: this.urls[uni.$u.random(0, this.urls.length - 1)],
});
}
},
//返回上一页
goBack() {
},
}
}
</script>
<style lang="scss" scoped>
.u-page {
padding: 10px;
background: rgb(249, 250, 251);
min-height: 100%;
box-sizing: border-box;
}
// 固定导航栏容器:固定在顶部,覆盖安全区
.navbar-container {
position: fixed; // 关键:固定定位,不随滚动移动
top: 0;
left: 0;
right: 0;
background: rgb(148, 194, 247); // 和页面背景一致,避免穿透
z-index: 999; // 确保导航栏在最上层,不被内容覆盖
box-sizing: border-box;
padding: 0 10px; // 和页面容器的padding对齐,避免导航栏内容偏移
}
.navbarBox {
height: 40px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 10px;
}
.placeholder {
width: 28px;
height: 28px;
}
.navbarBox p {
margin: 0;
font-size: 16px;
font-weight: 500;
white-space: nowrap;
}
.content-container {
width: 100%;
box-sizing: border-box;
overflow-y: auto;
padding-top: 10px; // 可选:给列表顶部加少量内边距,避免紧贴导航栏底部
}
</style>