开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感,从而使用户获得最佳的UI体验。本案例分别针对Navigation、滚动、Web页、底部弹框等场景实现了沉浸式适配,且介绍了实现沉浸式适配的两种方案。
使用说明:
页面的显示区域,默认不与系统设置的非安全区域比如状态栏、导航栏区域重叠,默认情况下开发者开发的界面都被布局在安全区域内。而要实现沉浸式效果,则需要设置组件绘制内容突破安全区域的限制。目前系统提供了两种方案:
Navigation沉浸式需要区分不同场景,如果是整个页面的背景色设置在Navigation组件,则对Navigation组件设置expandSafeArea熟悉使其整体绘制延伸至状态栏和导航条。若页面顶部和底部背景色不一致,需分别处理,如本案例单独对顶部组件设置了expandSafeArea熟悉使其绘制延伸至状态栏。详情见NavImmersive.ets。
Navigation(this.navPathStack) {
Column({ space: COLUM_SPACE }) {
...
}
.backgroundColor($r("app.color.immersive_column_bg_color"))
.width('100%')
// 设置顶部绘制延伸至状态栏
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
...
}
滚动场景需要对每一个嵌套的带有滚动的组件设置expandSafeArea属性,使其视窗范围扩展至导航条。
Scroll() {
...
}
.backgroundColor($r("app.color.immersive_list_bg_color"))
.padding({ bottom: $r("app.integer.immersive_column_padding_bottom") })
.width('100%')
.layoutWeight(LAYOUT_WEIGHT)
.scrollBar(BarState.Off)
.align(Alignment.Top)
// 将底部绘制延伸至导航条
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
GridRow({ gutter: { x: GUTTER_X, y: GUTTER_Y }, }) {
...
}
.padding({
left: $r("app.integer.immersive_grid_row_padding"),
right: $r("app.integer.immersive_grid_row_padding"),
top: $r("app.integer.immersive_grid_row_padding"),
bottom: $r("app.integer.immersive_grid_row_padding")
})
.backgroundColor($r("app.color.immersive_list_bg_color"))
// 设置列表绘制延伸至状态栏
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
Web场景则需要分为两块,title以及Web页,分别对其进行处理,然后在Web页中设置网页元素对安全区进行避让
Web({ src: $rawfile('web_immersive.html'), controller: this.controller })
.width('100%')
.layoutWeight(1)
// 设置Web绘制延伸到状态栏和导航条
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
...
<meta name='viewport' content='viewport-fit=cover, width=device-width, initial-scale=1.0'>
...
<style>
...
footer {
/* 网页元素对导航条进行避让 */
padding-bottom: env(safe-area-inset-bottom);
}
</style>
window.getLastWindow(getContext(), (err, windowClass) => {
...
// 设置窗口强制全屏布局
windowClass.setWindowLayoutFullScreen(true);
...
})
window.getLastWindow(getContext(), (err, windowClass) => {
...
// 获取导航条高度
this.bottomHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height;
// 获取状态栏高度
this.topHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height;
})
Column() {
...
}
.height('100%')
.width('100%')
.backgroundColor($r('app.color.immersive_background_color'))
// 设置padding避让状态栏及导航条
.padding({ top: px2vp(this.topHeight), bottom: px2vp(this.bottomHeight) })
底部弹框沉浸式场景只需要处理导航条,需要获取导航条高度,手动对其进行避让。
window.getLastWindow(getContext(), (err, data) => {
const avoidAreaBottom = data.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
this.bottomHeight = avoidAreaBottom.bottomRect.height;
})
...
List({ space: Constants.COMMENT_SPACE, scroller: this.scroller }) {
// TODO: 高性能知识点: LazyForEach按需加载,提高加载性能。
LazyForEach(this.data, (item: number, index: number) => {
ListItem() {
this.commentItem(index + 1) // index from 1
}
// 设置弹框尾部元素对导航条进行避让
.margin({ bottom: index === this.data.totalCount() - 1 ? px2vp(this.bottomHeight) : 0 })
}, (item: number) => item.toString())
}
...
不涉及
immersive // har类型
|---common
|---|---Constants.ets // 常量
|---components
|---|---Comment.ets // 商品评论
|---|---GoodsList.ets // 商品列表
|---mock
|---|---GoodsMock.ets // 商品列表mock数据
|---model
|---|---CommentDataSource.ets // 商品评论数据源
|---|---GoodsModel.ets // 商品实体类
|---dialog
|---|---ImmersiveDialog.ets // 底部弹框沉浸式适配
|---view
|---|---WebImmersive.ets // Web沉浸式适配
|---|---NavImmersive.ets // Navigation场景沉浸式适配,也是沉浸式适配场景入口
|---|---FullScreenImmersive.ets // 窗口全屏布局方案示例
|---|---GoodsDetails.ets // 商品详情页
不涉及
不涉及
本示例仅支持标准系统上运行。
本示例已适配API version 12版本SDK。
本示例需要使用DevEco Studio 5.0.0 Release及以上版本才可编译运行。
如需单独下载本工程,执行如下命令:
git init
git config core.sparsecheckout true
echo /code/UI/Immersive/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。