
#我的鸿蒙开发手记# HarmonyOS开发之如何实现沉浸式效果 原创 精华
本文基于HarmonyOSApi14。
沉浸式,在实际的开发中,可以说是无处不在,我们可以随便打开一个应用,比如京东淘宝,再比如支付宝微信,其顶部的透明化状态栏可以说是随处可见。
所谓的沉浸式效果主要指通过隐藏或透明化状态栏和导航栏,使应用内容扩展至屏幕边缘,主要用于提升用户体验,如果没有沉浸式,在UI视觉上就会有差异感,体验感是非常的不好,如下的效果,当你不是沉浸式时,就会和顶部的状态栏有明显的差异。
那么,在鸿蒙当中如何来实现一个沉浸式效果呢,目前有多种实现方式可以供我们选择。
全局统一设置
如果我们想针对整个应用都设置沉浸式,我们就可以使用全局统一设置,这样,我们所有的子页面都会进行沉浸式展示,主要是通过window中setWindowLayoutFullScreen方法来设置。
我们可以在主入口的EntryAbility里进行设置:
onWindowStageCreate(windowStage: window.WindowStage): void {
let windowClass: window.Window = windowStage.getMainWindowSync()
windowClass.setWindowLayoutFullScreen(true).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));
});
}
当然你也可以使用Promise异步获取的方式拿到window,代码如下:
let window=await windowStage.getMainWindow()
以上的代码设置之后需要注意,安全区域的内容,需要避开导航条和状态栏,否则就会被状态栏和导航栏覆盖。
以上的效果可以看到,再设置沉浸式之后,由于没有避让,我们的UI视图直接被上移了,这种情况下,我们就需要把整体的UI视图,在状态栏之下,可以先获取状态栏的高度,然后进行设置即可:
Column() {
Text("我是测试标题")
.width("100%")
.height(40)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}.width("100%")
.padding({ top: this.navHeight })
.backgroundColor(Color.Pink)
可以看到,我们的标题已经正常展示了。
获取状态栏和导航栏高度的代码如下:
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
let avoidArea = windowClass.getWindowAvoidArea(type);
let bottomRectHeight = avoidArea.bottomRect.height; //获取导航栏高度
let type = window.AvoidAreaType.TYPE_SYSTEM;
let avoidArea = win.getWindowAvoidArea(type);
let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
有一点需要说的是,如果你的沉浸式是纯颜色的,其实,我们可以直接设置状态栏的颜色即可,其他的代码都不需要修改。
let windowClass: window.Window = windowStage.getMainWindowSync()
let SystemBarProperties: window.SystemBarProperties = {
statusBarColor: '#FFC0CB',
statusBarContentColor: "#ffffff",
};
try {
windowClass.setWindowSystemBarProperties(SystemBarProperties).then(() => {
console.info('Succeeded in setting the system bar properties.');
}).catch((err: BusinessError) => {
console.error(`Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`);
});
} catch (exception) {
console.error(`Failed to set the system bar properties. Cause code: ${exception.code}, message: ${exception.message}`);
}
单页面设置
单页面的话,我们可以直接获取getLastWindow,然后设置。
aboutToAppear(): void {
window.getLastWindow(getContext(), (_, win) => {
win.setWindowLayoutFullScreen(true).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));
});
})
}
除了以上的方式之外,单页面更多的是通过安全区域来实现沉浸式,所谓的安全区域就是指页面的显示区域,也就是状态栏、导航栏区域之外的区域。
如何让安全区域,延伸到状态栏、导航栏,达到沉浸式的效果,其实在鸿蒙中给我们提供expandSafeArea,通过它我们就可以设置到任意的组件上。
Column() {
}.height("100%")
.width("100%")
.backgroundColor(Color.Gray)
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
我们看下实际的运行效果,可以看到,导航栏和状态栏均已实现了沉浸式。
分析expandSafeArea
通过源码,我们可以看到,expandSafeArea接收了两个参数,第一个参数types,类型是Array <SafeAreaType>,通过问号,我们可以知道,这个不是必须得,主要配置扩展安全区域的类型,当未添加metadata配置项时,页面不避让挖孔, CUTOUT类型不生效;第二个参数edges,类型是Array <SafeAreaEdge>,也是不是必须的,配置扩展安全区域的方向。
expandSafeArea(types?: Array<SafeAreaType>, edges?: Array<SafeAreaEdge>): T;
SafeAreaType
扩展安全区域的枚举类型
名称 | 描述 |
SYSTEM | 系统默认非安全区域,包括状态栏、导航栏。 |
CUTOUT | 设备的非安全区域,例如刘海屏或挖孔屏区域。 |
KEYBOARD | 软键盘区域。 |
SafeAreaEdge
扩展安全区域的方向
名称 | 描述 |
TOP | 上方区域。 |
BOTTOM | 下方区域。 |
START | 前部区域。 |
END | 尾部区域。 |
使用须知
在使用expandSafeArea属性时,有几点需要注意,第一个就是,在可滚动的容器中使用是没有效果的,比如List组件,Scroll组件等等;第二个就是,expandSafeArea属性是给组件设置的,不会影响到别的页面,只对当前的页面有效果,所以,如果是整个项目都是沉浸式,建议选择应用窗口管理进行实现,第三个就是使用到了expandSafeArea属性后,它会延伸至非安全区域,也就是扩展到导航栏和状态栏,在内容区域中,需要控制好组件的位置,避免状态栏或导航栏覆盖内容区域。
