跳到主要内容

06开发应用沉浸式效果

开发应用沉浸式效果


Navigation布局默认沉浸式效果,无需再专门设置。本案例针对非Navigation布局使用。


开发应用沉浸式效果

扩展组件的安全区域

设置组件的 expandSafeArea 属性,扩展组件的安全区域到状态栏和导航栏,从而实现沉浸式。

import { router } from '@kit.ArkUI'

/*
* 引导页 :定时跳转到Index页面。
* 1. 设置组件的 expandSafeArea 属性,扩展组件的安全区域到状态栏和导航栏,从而实现沉浸式。例如背景图扩展
* 推荐Navigation跳转页面 但是Navigation默认沉浸式 所以此案例暂时使用router跳转(已过时,但可跳转)
* */
@Entry
@Component
struct Guide {

second :number = 3

aboutToAppear(): void {
setTimeout(() => {
router.pushUrl({
url:"pages/Index"
})
},this.second*1000)
}

build() {
Column({ space: 30 }) {
Text(`引导页,${this.second}秒钟后跳转到首页`).fontSize(22).fontColor('#fffc0303')
}
.width('100%')
.height('100%')
.backgroundImage($r('app.media.bg'))
.backgroundImageSize({ width: '100%', height: '100%' })
.justifyContent(FlexAlign.Center)
// 设置顶部/底部 延伸到状态栏/导航条
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}
}

使用 Window.setWindowLayoutFullScreen()方法设置窗口为全屏模式。


先准备工具类

src/main/ets/dxinUtils/DxinScreenManager.ets

import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

/*
* @des 沉浸式屏幕效果。参考官方文档+极客马拉松等
* @author dxin
* */
class DxinScreenManager {
private static instance: DxinScreenManager; // 单例设计模式
private topSafeHeight: number = 0;
private bottomSafeHeight: number = 0;

public static getInstance(): DxinScreenManager {
if (!DxinScreenManager.instance) {
DxinScreenManager.instance = new DxinScreenManager();
}
return DxinScreenManager.instance;
}
//获取顶部安全区域高度
getTopSafeHeight() {
return this.topSafeHeight;
}
//获取底部安全区域高度
getBottomSafeHeight() {
return this.bottomSafeHeight;
}

/*
* @des 开启沉浸式
* */
setFullScreen(windowStage: window.WindowStage) {
let windowClass: window.Window = windowStage.getMainWindowSync()
let isLayoutFullScreen = true
try {
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
let bottomType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
let bottomAvoidArea = windowClass.getWindowAvoidArea(bottomType)
let bottomRectHeight = bottomAvoidArea.bottomRect.height //底部导航栏高度

let topType = window.AvoidAreaType.TYPE_SYSTEM
let topAvoidArea = windowClass.getWindowAvoidArea(topType)
let topAvoidHeight = topAvoidArea.topRect.height //顶部状态栏高度

this.setTopSafeHeight(px2vp(topAvoidHeight))
this.setBottomSafeHeight(px2vp(bottomRectHeight))
} catch (e) {
console.log("fullScreenError", e)
}
}

/*
* @des 注册监听函数
* */
registerWindowListener(windowStage: window.WindowStage) {
let windowClass: window.Window = windowStage.getMainWindowSync()
// 3. 注册监听函数,动态获取避让区域数据
windowClass.on('avoidAreaChange', (data) => {
if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
let topRectHeight = data.area.topRect.height;
this.setTopSafeHeight(px2vp(topRectHeight))
} else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
let bottomRectHeight = data.area.bottomRect.height;
this.setBottomSafeHeight(px2vp(bottomRectHeight))
}
});
}


//存储顶部安全区域高度
private setTopSafeHeight(topSafeHeight: number) {
this.topSafeHeight = topSafeHeight;
}
//存储底部安全区域高度
private setBottomSafeHeight(bottomSafeHeight: number) {
this.bottomSafeHeight = bottomSafeHeight;
}
}

export const dxinScreenManager = DxinScreenManager.getInstance()

入口类调用工具类设置沉浸式

src/main/ets/entryability/EntryAbility.ets

onWindowStageCreate(windowStage: window.WindowStage): void {

windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
return;
}
});

//开启沉浸式
dxinScreenManager.setFullScreen(windowStage)
}

在UI中设置内边距

src/main/ets/pages/Index.ets

import { dxinScreenManager } from '../dxinUtils/DxinScreenManager';

@Entry
@Component
struct Index {
@State titleFlag: boolean = false

build() {
Column({ space: 30 }) {
Text('沉浸式效果')
.fontSize(22)
.fontColor(this.titleFlag ? '#fffa0000' : '#ff0031de')
.onClick(() => {
this.titleFlag = !this.titleFlag
})
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.theme_color'))
.padding({
top:dxinScreenManager.getTopSafeHeight(),
bottom:dxinScreenManager.getBottomSafeHeight()
})
}
}

处理避让区域和页面内容的适配问题

由于避让区本身是有内容展示,如状态栏中的电量、时间等系统信息,或是手势交互,如导航条点击或上滑,在实现应用页面沉浸式效果后,往往会和避让区域产生UI元素的遮挡、视觉上的违和或交互上的冲突等问题,开发者可以针对不同场景选择以下方式对避让区和应用页面进行适配。