文章目录
- 问题原因:
- 解决方案:
今天刚遇到的问题,横屏的页面完成操作后跳转页面后,自定义的tabbar样式乱了,跑到最顶了,真机调试后发现navbar跑到手机状态栏了,它正常应该跟右边胶囊一行。
知道问题了就好办了,先分析
正常的屏幕显示应该是:
- 竖屏:导航栏高度 = 状态栏高度 + 44px(内容区)
- 横屏:导航栏高度 = 44px(仅内容区)
问题原因:
- 屏幕旋转时,系统信息(如状态栏高度)会发生变化
- 在横竖屏切换过程中,获取系统信息可能存在时序问题,导致获取到的状态栏高度不准确
解决方案:
- 监听屏幕旋转事件 wx.onWindowResize
- 通过比较窗口宽高来判断是否横屏:windowWidth > windowHeight
- 在横屏时将状态栏高度设置为0,竖屏时使用系统实际状态栏高度
- 使用 setTimeout 延迟更新导航栏状态,确保系统信息已完全更新
- 在组件销毁时,记得解绑旋转事件监听器 wx.offWindowResize()
下面是具体custom-navbar组件的代码,这里只是适用我的项目,应该不是完美的方案,有更好的方案欢迎大家沟通
custom-navbar.wxml
<view class="navbar-container">
<!-- 导航栏主体 -->
<view class="navbar {{isLandscape ? 'landscape' : ''}}">
<!-- 状态栏占位 -->
<view class="status-bar" style="height: {{statusBarHeight}}px"></view>
<!-- 导航栏内容 -->
<view class="navbar-content">
<view class="left">
<view wx:if="{{showBack}}" class="back-icon" bind:tap="onBack">
<t-icon name="chevron-left" class="nav-icon" />
</view>
<view wx:if="{{showHome}}" class="home-icon" bind:tap="onGoHome">
<t-icon name="home" class="nav-icon" />
</view>
</view>
<view class="center">
<text>{{title}}</text>
</view>
<view class="right"></view>
</view>
</view>
<!-- 占位元素 -->
<view class="navbar-placeholder" style="height: {{isLandscape ? 44 : (44 + statusBarHeight)}}px"></view>
</view>
custom-navbar.wxss
.navbar-container {
width: 100%;
position: relative;
z-index: 999;
}
.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #fff;
z-index: 999;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.status-bar {
width: 100%;
background: #fff;
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
padding: 0 12px;
position: relative;
background: #fff;
}
.left {
display: flex;
align-items: center;
min-width: 90px;
position: relative;
z-index: 2;
}
.back-icon, .home-icon {
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
}
.back-icon .nav-icon {
font-size: 50rpx;
}
.home-icon .nav-icon {
font-size: 40rpx;
}
.icon-image {
width: 24px;
height: 24px;
}
.center {
flex: 1;
text-align: center;
font-size: 17px;
font-weight: 500;
color: #000;
position: absolute;
left: 0;
right: 0;
z-index: 1;
height: 44px;
line-height: 44px;
}
.right {
min-width: 90px;
position: relative;
z-index: 2;
}
/* 导航栏占位元素 */
.navbar-placeholder {
width: 100%;
background: transparent;
}
/* 为使用自定义导航栏的页面提供的全局样式类 */
.with-custom-navbar {
padding-top: env(safe-area-inset-top);
min-height: 100vh;
box-sizing: border-box;
background: #f5f5f5;
}
/* 横屏模式样式 */
.navbar.landscape {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 44px;
padding: 0;
margin: 0;
}
.navbar.landscape .status-bar {
display: none;
}
.navbar.landscape .navbar-content {
height: 44px;
padding: 0 8px;
margin: 0;
}
.navbar.landscape .back-icon .nav-icon {
font-size: 32rpx;
}
.navbar.landscape .home-icon .nav-icon {
font-size: 28rpx;
}
.navbar.landscape .center {
font-size: 14px;
height: 44px;
line-height: 44px;
}
.navbar.landscape .back-icon,
.navbar.landscape .home-icon {
padding: 4px;
}
custom-navbar.js
Component({
properties: {
// 标题
title: {
type: String,
value: ''
},
// 是否显示返回按钮
showBack: {
type: Boolean,
value: true
},
// 是否显示首页按钮
showHome: {
type: Boolean,
value: true
},
// 首页路径
homePath: {
type: String,
value: '/pages/index/index'
}
},
data: {
statusBarHeight: 0,
isLandscape: false
},
lifetimes: {
attached() {
this.updateNavBarStatus();
// 监听屏幕旋转
wx.onWindowResize((res) => {
const { windowWidth, windowHeight } = res.size;
const newIsLandscape = windowWidth > windowHeight;
if (this.data.isLandscape !== newIsLandscape) {
// 延迟一下更新,确保系统信息已经更新
setTimeout(() => {
this.updateNavBarStatus();
}, 100);
}
});
},
detached() {
wx.offWindowResize();
}
},
methods: {
// 更新导航栏状态
updateNavBarStatus() {
try {
const systemInfo = wx.getSystemInfoSync();
const isLandscape = systemInfo.windowWidth > systemInfo.windowHeight;
console.log('系统信息:', systemInfo);
console.log('是否横屏:', isLandscape);
console.log('状态栏高度:', systemInfo.statusBarHeight);
this.setData({
isLandscape: isLandscape,
statusBarHeight: isLandscape ? 0 : (systemInfo.statusBarHeight || 48)
});
} catch (error) {
console.error('获取系统信息失败:', error);
// 设置默认值
this.setData({
statusBarHeight: 48
});
}
},
// 返回上一页
onBack() {
const pages = getCurrentPages();
if (pages.length > 1) {
wx.navigateBack();
} else {
wx.reLaunch({
url: this.data.homePath
});
}
this.triggerEvent('back');
},
// 返回首页
onGoHome() {
wx.reLaunch({
url: '/pages/index/index',
});
this.triggerEvent('home');
}
}
});
custom-navbar.json
{
"component": true,
"usingComponents": {
"t-navbar": "tdesign-miniprogram/navbar/navbar",
"t-icon": "tdesign-miniprogram/icon/icon"
}
}