HarmonyOS鸿蒙Next中沉浸式效果避让策略失效该如何解决
HarmonyOS鸿蒙Next中沉浸式效果避让策略失效该如何解决
【问题现象】
在应用中实现沉浸式效果时:
- 当设置FullScreen属性后,Navigation导航栏不会避让状态栏,而Navigation导航栏使用padding来避让状态栏后,这一设置会影响所有navDestination页面。
- 当不设置FullScreen属性,需要铺满全屏的页面,不能在时间栏和系统底部导航条区域渲染。
具体效果如下:
【背景知识】
1. 窗口全屏布局方案
调整布局系统为全屏布局,界面元素延伸到状态栏和导航条区域实现沉浸式效果。当不隐藏避让区时,可通过接口查询状态栏和导航条区域进行可交互元素避让处理,并设置状态栏或导航条的颜色等属性与界面元素匹配。当隐藏避让区时,通过对应接口设置全屏布局即可。
参考链接:窗口全屏布局方案。
2. 组件安全区方案
布局系统保持安全区内布局,然后通过接口延伸绘制内容(如背景色,背景图)到状态栏和导航条区域实现沉浸式效果。该方案下,界面元素仅做绘制延伸,无法单独布局到状态栏和导航条区域,针对需要单独布局UI元素到状态栏和导航条区域的场景建议使用窗口全屏布局方案处理。
参考链接:组件安全区方案。
3. padding:组件内边距
参考链接:组件尺寸设置。
4. @StorageLink
参考链接:应用全局的UI状态。
【解决方案】
针对不同场景下的沉浸式效果需求,可以选择设置或不设置FullScreen属性,采用不同的解决方案处理对应的问题。
1. 设置FullScreen
- 当应用中大多数页面需要全屏渲染时,可以在onWindowStageCreate方法中全局设置windowLayoutFullScreen为true。或者在需要的场景内单独设置windowLayoutFullScreen为true,退出时恢复原值。
- 代码示例如下:
EntryAbility.ets
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
// 此处添加以下代码
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));
});
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.')
});
}
xxxPage.ets
import { window } from '@kit.ArkUI';
@Entry
@Component
export struct xxxPage {
// page中使用此方式设置是否开启FullScreen
setFullScreen(value:boolean) {
window.getLastWindow(getContext(this)).then(currentWindow => {
currentWindow.setWindowLayoutFullScreen(value);
});
}
build() {
Column() {
...
}
.height('100%')
.width('100%')
}
}
在FullScreen模式下,Navigation的TitleBar会被顶部状态栏遮挡,底部Tab组件会被系统导航条遮挡。可以通过设置padding来手动避让,设置padding后子页面也会受到影响,需要更新Navigation根页面中设置的padding才生效,使用AppStorage可以设置此padding值。
效果如下:
代码示例如下:
Index.ets
AppStorage.setOrCreate('safeTop', 0);
AppStorage.setOrCreate('safeBottom', 0);
@Entry
@Component
struct Index {
[@StorageLink](/user/StorageLink)('safeTop') safeTop:number = 0;
[@StorageLink](/user/StorageLink)('safeBottom') safeBottom:number = 0;
build() {
Navigation() {
...
}
.height('100%')
.width('100%')
.padding({
top: this.safeTop,
bottom: this.safeBottom,
})
}
}
xxxPage.ets
@Entry
@Component
export struct xxxPage {
[@StorageLink](/user/StorageLink)('safeTop') safeTop:number = 0;
[@StorageLink](/user/StorageLink)('safeBottom') safeBottom:number = 0;
// 其他page中直接修改
setSafeTop() {
window.getLastWindow(getContext(this)).then(windowClass => {
let topType = window.AvoidAreaType.TYPE_SYSTEM
let statusBarArea = windowClass.getWindowAvoidArea(topType);
this.safeTop = statusBarArea.topRect.height;
});
}
setSafeTop() {
window.getLastWindow(getContext(this)).then(windowClass => {
let bottomType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
let bottomArea = windowClass.getWindowAvoidArea(bottomType);
this.safeBottom = bottomArea.bottomRect.height;
});
}
build() {
Column() {
...
}
}
}
2. 不设置FullScreen
当应用中大多数页面需要避让系统顶部状态栏和底部导航条时,可以不使用FullScreen模式,使用组件的扩展安全区域方式。当组件布局不需要避让时,可以通过expandSafeArea属性让组件渲染到非安全区。List 组件还可以通过contentStartOffset和contentEndOffset 设置内容顶部和底部的空余高度。
代码示例如下:
Column() {
List() {
}
.contentStartOffset(this.safeArea.top)
.contentEndOffset(this.safeArea.bottom)
}
// 设置底部绘制延伸到头部时间栏和底部导航条
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
【总结】
在应用开发中实现沉浸式效果时,需要根据具体需求选择是否设置FullScreen属性。设置FullScreen属性可以实现全屏渲染,但需要手动避让状态栏和导航条。不设置FullScreen属性则通过组件的扩展安全区域方式避让系统栏。了解并灵活运用这两种方式,可以更好地实现应用的沉浸式效果。
更多关于HarmonyOS鸿蒙Next中沉浸式效果避让策略失效该如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中沉浸式效果避让策略失效该如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,沉浸式效果避让策略失效的解决方案如下:
1. 设置FullScreen属性
- 在
onWindowStageCreate
方法中全局设置windowLayoutFullScreen
为true
,或在需要的场景内单独设置windowLayoutFullScreen
为true
,退出时恢复原值。 - 使用
AppStorage
设置padding
值,手动避让状态栏和导航条。
2. 不设置FullScreen属性
- 使用组件的扩展安全区域方式,通过
expandSafeArea
属性让组件渲染到非安全区。 - 对于
List
组件,使用contentStartOffset
和contentEndOffset
设置内容顶部和底部的空余高度。
根据具体需求选择是否设置FullScreen
属性,灵活运用这两种方式实现沉浸式效果。