鸿蒙API9和API10没有实现沉浸式窗口的方式。沉浸式窗口是Android 5.0(API 21)引入的一项功能,它允许应用占据整个屏幕,隐藏系统栏,提供更沉浸式的用户体验。在API 9和API 10中,没有提供实现沉浸式窗口的官方API或方法。这些版本的功能和API与沉浸式窗口的实现不兼容。因此,要在这些版本上实现类似沉浸式窗口的效果,需要使用自定义的解决方案或第三方库。
在API9中实现方式
onWindowStageCreate(windowStage: window.WindowStage) {
// API9 全屏判断
let isLayoutFullScreen = true;
let windowClass = null;
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if(err.code){
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
windowClass = data;
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
// API9设置窗口全屏化
try {
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => {
if(err.code){
console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in setting the window layout to full-screen mode.');
});
} catch (exception) {
console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(exception));
}
// API9不显示导航栏、状态栏
// 如果需要沉浸式,将 names = [];
let names = [];
try {
windowClass.setWindowSystemBarEnable(names, (err) => {
if(err.code){
console.error('Failed to set the system bar to be invisible. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in setting the system bar to be invisible.');
});
} catch (exception) {
console.error('Failed to set the system bar to be invisible. Cause:' + JSON.stringify(exception));
}
}
在API10中实现方式
@Entry
@Component
struct Index {
@State message: string = '内容栏全屏测试'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
}
.height('100%')
.backgroundColor(Color.Orange)
}
}
隐藏状态栏、导航栏可以达到完全沉浸的效果,使用setWindowSystemBarEnable接口即可实现。
图片背景通
这种方案可以实现图片背景的通铺,同时又能避免状态栏和导航栏的内容跟应用内容相互遮挡,导致显示效果异常。为了能让应用的有效显示范围避开系统的状态栏和导航栏,以免内容重叠,我们可以通过windowClass.on(type: ‘avoidAreaChange’, callback: Callback<{AvoidAreaType, AvoidArea}>) 获取系统规避区域的大小,并对这一块区域做出相应的规避。其中回调参数AvoidArea是规避区域,可以通过其获取规避区域的具体范围;AvoidAreaType是规避区域的类型其取值如下,示例中需要规避的状态栏和导航栏属于TYPE_SYSTEM类型。
名称 | 值 | 说明 |
---|---|---|
TYPE_SYSTEM | 0 | 表示系统默认区域。 |
TYPE_CUTOUT | 1 | 表示刘海屏区域。 |
TYPE_SYSTEM_GESTURE9+ | 2 | 表示手势区域。 |
TYPE_KEYBOARD9+ | 3 | 表示软键盘区域 |
具体代码如下: |
page代码
// index.ets
@Entry
@Component
struct Type3 {
@State message: string = 'Hello World'
@StorageLink("topHeight") topHeight: number = 0
@StorageLink("bottomHeight") bottomHeight: number = 0
build() {
Column() {
// 在界面顶部放置一个Row组件,用于占位
Row() {
}
.width("100%")
// 设置Row组件的高度为状态栏的高度,可避免界面内容与状态栏内容重叠
.height(px2vp(this.topHeight))
Row() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.position({ x: 0, y: 0 })
}
.width("100%")
.flexGrow(1)
// 在界面底部放置一个Row组件,用于占位
Row() {
}
.width("100%")
// 设置Row组件的高度为导航栏的高度,可避免界面内容与导航栏内容重叠
.height(px2vp(this.bottomHeight))
}
.backgroundImage($r("app.media.icon"))
.backgroundImageSize(ImageSize.Cover)
.width("100%")
.height("100%")
}
}
复制
ability代码
// MainAbility.ts
import window from '@ohos.window';
async function enterImmersion(windowClass: window.Window) {
// 获取状态栏和导航栏的高度
windowClass.on("avoidAreaChange", ({ type, area }) => {
if (type == window.AvoidAreaType.TYPE_SYSTEM) {
// 将状态栏和导航栏的高度保存在AppStorage中
AppStorage.SetOrCreate<number>("topHeight", area.topRect.height);
AppStorage.SetOrCreate<number>("bottomHeight", area.bottomRect.height);
}
})
// 设置窗口布局为沉浸式布局
await windowClass.setWindowLayoutFullScreen(true)
await windowClass.setWindowSystemBarEnable(["status", "navigation"])
// 设置状态栏和导航栏的背景为透明
await windowClass.setWindowSystemBarProperties({
navigationBarColor: "#00000000",
statusBarColor: "#00000000",
navigationBarContentColor: "#FF0000",
statusBarContentColor: "#FF0000"
})
}
export default class MainAbility extends Ability {
...
async onWindowStageCreate(windowStage: window.WindowStage) {
let windowClass:window.Window = await windowStage.getMainWindow()
await enterImmersion(windowClass)
windowStage.loadContent('pages/page5')
}
...
}
关注我获取更多知识或者投稿