HarmonyOS基础:如何使tabbar/navbar背景色不能衍生到状态栏和导航栏? 原创
鸿蒙应用窗口全屏设置指南
问题背景
在开发鸿蒙应用时,当使用Tabs组件时会遇到一个常见问题:Tabs组件只能放置在内容区域,而导航栏和状态栏区域会保持原有的背景颜色,这样会导致整体视觉体验不统一,影响应用的美观性。
解决方案
1. 窗口全屏布局方案
调用窗口强制全屏布局接口(setWindowLayoutFullScreen())实现界面元素覆盖到状态栏和导航条,获取到状态栏和导航条高度后进行避让处理
该布局方案相对灵活,开发者可以通过获取到状态栏和导航条的区域,从而进行避让处理。
- 调用setWindowLayoutFullScreen()接口设置窗口全屏。
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
// 1. 设置窗口全屏
let isLayoutFullScreen = true;
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
.then(() => {
console.info('Succeeded in setting the window layout to full-screen mode.');
})
.catch((err: BusinessError) => {
console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
});
});
}
}
- 使用getWindowAvoidArea()接口获取布局遮挡区域(例如状态栏、导航条)
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
// 1. 设置窗口全屏
// ...
// 2. 获取布局避让遮挡的区域
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
let avoidArea = windowClass.getWindowAvoidArea(type);
let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度
AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); // 创建本地存储
});
}
}
- 根据遮挡区域高度,调整页面内容区域位置,实现避让效果。
let storage = LocalStorage.getShared();
@Entry(storage)
@Component
struct Index {
bottomRectHeight: string = AppStorage.get<number>('bottomRectHeight') + 'px';
build() {
Row() {
Column() {
Row() {
Text('ROW1').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW2').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW3').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW4').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW5').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW6').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#008000')
}
.margin({ bottom: this.bottomRectHeight }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
}
}
2. 组件安全区方案
如果上述全屏方案不适合您的应用场景,还可以使用组件安全区方案。通过设置组件的expandSafeArea
属性,可以让组件扩展到系统安全区以外的区域。
图例:界面元素自动避让状态栏和导航条示意图
针对上面的情况,状态栏和导航条不匹配问题,可以通过窗口的背景色来实现统一背景色效果。使用setWindowBackgroundColor()接口设置窗口背景色。
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
// 设置全窗颜色和应用内容颜色一致
let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
windowClass.setWindowBackgroundColor('#008000'); // 设置窗口背景色
});
}
}
在设置窗口背景色后,把页面内容背景也设置和窗口颜色一样,从而实现统一背景色效果。
// Index.ets
@Entry
@Component
struct Index {
build() {
Column() {
Text('Hello World').fontSize(40)
}
.backgroundColor('#008000')
}
}
这样就实现了状态栏和导航条区域与页面内容背景色一致的效果。
那如果状态栏和导航条和页面内容颜色不同怎么办?
可以通过设置组件的expandSafeArea属性来扩展安全区域,并设置不同的背景色,个人比较推荐这个方案,因为可以实现状态栏和导航条区域与页面内容背景色不一致/一致的效果,非常灵活。
例如:
// xxx.ets
@Entry
@Component
struct Example {
build() {
Column() {
Row() {
Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
}
.backgroundColor('#F08080')
// 设置顶部绘制延伸到状态栏
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
Row() {
Text('ROW2').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW3').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW4').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW5').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
}
.backgroundColor(Color.Orange)
// 设置底部绘制延伸到导航条
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
}
.width('100%').height('100%').alignItems(HorizontalAlign.Center)
.backgroundColor('#008000')
.justifyContent(FlexAlign.SpaceBetween)
}
}
效果如下:
引用:
@ohos.window (窗口)
开发应用沉浸式效果
获取状态栏高度的方法
结语
本篇文章的内容结束了。文章错误/不完整的地方,望多指点;
望更多小伙伴们加入harmonyOS开发大家庭,壮大生态圈,让鸿蒙更好,让国产手机应用(物联网)系统更强大。
鸿蒙5.0已经在公测了。和小伙伴一起加油,鸿蒙不仅仅应用开发系统。也会在物联网等领域大展拳脚。鸿蒙之父说:“手机端只是鸿蒙的5%的潜能。应用开发只是第一步,还有更多潜能供我们发觉开发"。
如对你学习有所帮助,希望可爱你动动小手,关注、点赞、收藏;
我也遇到了这个问题
完美解决