探秘鸿蒙 HarmonyOS NEXT:沉浸式页面开发实战攻略

打印 上一主题 下一主题

主题 924|帖子 924|积分 2772

概述

本文章基于HarmonyOS NEXT操纵系统,API12以上的版本。
沉浸式开发模式,旨在让应用界面高度聚焦于内容呈现,最大程度制止用户受到无关元素的干扰。在移动端应用里,全屏窗口由状态栏、应用界面和导航栏构成。在进行沉浸式页面开发时,通常会接纳将应用页面拓展至状态栏和导航栏地区的方式,以此实现以下目的:


  • 使页面和避让地区的色调统一,为用户提供更好的视觉体验。
  • 最大程度利用屏幕可视地区,使页面获得更大的结构空间。
  • 提供完全沉浸的体验,让用户沉浸其中,不被其他事物所干扰。
本文将先容沉浸式页面的实现方案、原理以及提供以下常见沉浸式页面开发场景下一些适配题目的办理方案。


  • [顶部或底部背景延伸场景]
  • [顶部图片延伸场景]
  • [滚动列表底部延伸场景]
  • [全屏沉浸式场景]
  • [深色背景下状态栏颜色适配场景]

实现原理

针对上面的计划要求,可以通过如下两种方式实现应用沉浸式效果:


  • [窗口全屏结构方案]:调解结构系统为全屏结构,界面元素延伸到状态栏和导航条地区实现沉浸式效果。当不隐蔽避让区时,可通过接口查询状态栏和导航条地区进行可交互元素避让处理,并设置状态栏或导航条的颜色等属性与界面元素匹配。当隐蔽避让区时,通过对应接口设置全屏结构即可。
  • [组件安全区方案]:结构系统保持安全区内结构,然后通过接口延伸绘制内容(如背景色,背景图)到状态栏和导航条地区实现沉浸式效果。
怎样区分或利用?
组件安全区该方案下,界面元素仅做绘制延伸,无法单独结构到状态栏和导航条地区,针对必要单独结构UI元素到状态栏和导航条地区的场景建议利用窗口全屏结构方案处理。
关键技能

方案一:利用 Window.setWindowLayoutFullScreen() 方法设置窗口为全屏模式。
这种方案一样寻常实用于一级界面Index中,要根据需求,看结构中的UI元素是否必要避让状态栏和导航条,否则可能产生UI元素重叠等情况。
如果,对控件顶部设置padding(具体数值与状态栏高度一致),实现对状态栏的避让;对底部设置padding(具体数值与底部导航条地区高度一致),实现对底部导航条的避让。
如果,去掉顶部和底部的padding设置,即不避让状态栏和导航条,UI元素就会发生重叠。
代码如下:
  1. import { UIAbility } from '@kit.AbilityKit';
  2. import { window } from '@kit.ArkUI';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. export default class EntryAbility extends UIAbility {
  5.   onWindowStageCreate(windowStage: window.WindowStage) {
  6.     // 1.获取应用主窗口。
  7.     let windowClass: window.Window | undefined = undefined;
  8.     windowStage.getMainWindow().then(windowClass => {
  9.       console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(windowClass));
  10.       // 2.设置窗口全屏,实现沉浸式效果。
  11.       windowClass.setWindowLayoutFullScreen(true).then(() => {
  12.         console.info('Succeeded in setting the window layout to full-screen mode.');
  13.       }).catch((e: BusinessError) => {
  14.         console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(e));
  15.       })
  16.     }).catch((err: BusinessError) => {
  17.       console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
  18.     })
  19.     // 3.为沉浸式窗口加载对应的目标页面。
  20.     windowStage.loadContent("pages/Index", (err) => {
  21.       if (err.code) {
  22.         console.error('Failed to load the content. Cause:' + JSON.stringify(err));
  23.         return;
  24.       }
  25.       console.info('Succeeded in loading the content.');
  26.     });
  27.   }
  28. };
复制代码
方案二:设置组件的 expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 属性,扩展组件的安全地区到状态栏和导航栏,从而实现沉浸式。
代码如下:
  1. @Entry
  2. @Component
  3. struct Example {
  4.   build() {
  5.     Column() {
  6.       Row() {
  7.         Text('Top Row')
  8.           .fontSize(40)
  9.           .textAlign(TextAlign.Center)
  10.           .width('100%')
  11.       }
  12.       .backgroundColor('#F08080')
  13.       // 设置顶部绘制延伸到状态栏
  14.       .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  15.       Row() {
  16.         Text('ROW2')
  17.           .fontSize(40)
  18.       }
  19.       .backgroundColor(Color.Orange)
  20.       .padding(20)
  21.       Row() {
  22.         Text('ROW3')
  23.           .fontSize(40)
  24.       }
  25.       .backgroundColor(Color.Orange)
  26.       .padding(20)
  27.       Row() {
  28.         Text('ROW4')
  29.           .fontSize(40)
  30.       }
  31.       .backgroundColor(Color.Orange)
  32.       .padding(20)
  33.       Row() {
  34.         Text('ROW5')
  35.           .fontSize(40)
  36.       }
  37.       .backgroundColor(Color.Orange)
  38.       .padding(20)
  39.       Row() {
  40.         Text('Bottom Row')
  41.           .fontSize(40)
  42.           .textAlign(TextAlign.Center)
  43.           .width('100%')
  44.       }
  45.       .backgroundColor(Color.Orange)
  46.       // 设置底部绘制延伸到导航条
  47.       .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  48.     }
  49.     .width('100%')
  50.     .height('100%')
  51.     .alignItems(HorizontalAlign.Center)
  52.     .backgroundColor('#008000')
  53.     .justifyContent(FlexAlign.SpaceBetween)
  54.   }
  55. }
复制代码
场景分析

场景一 顶部或底部背景延伸场景

场景形貌

页面背景必要延伸到状态栏和导航条地区,页面内容在安全区展示。

开发步骤

利用[expandSafeArea]属性扩展背景组件安全地区
给设置背景色的组件设置expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]),使背景色延伸到状态栏和导航条。由于[expandSafeArea]属性不影响子组件的结构,以是Tabs组件内的内容默认在安全地区结构,避让状态栏和导航条。
代码如下:
  1. Tabs({ barPosition: BarPosition.End }) {
  2.   // ...
  3. }
  4. .backgroundColor('#F1F3F5')
  5. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
复制代码
场景二 顶部图片延伸场景

场景形貌

页面顶部的图片要延伸到状态栏中去,形成沉浸式效果。顶部的返回按钮等交互组件,要合理避让状态栏。

开发步骤


  • 设置图片expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]),扩展图片上方的安全地区。由于[expandSafeArea]属性不影响兄弟组件的结构,顶部的按钮地区默认避让状态栏。
  • 设置Swiper组件的[clip]属性为false,不裁剪内部组件。在设置[expandSafeArea]属性的组件的父组件是滚动类容器时,需配合[clip]属性利用。
代码如下:
  1. Swiper(this.swiperController) {
  2.   ForEach(BANNER_IMAGES, (image: Resource) => {
  3.     Image(image)
  4.       .width('100%')
  5.       .height('100%')
  6.       .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  7.   }, (image: Resource) => JSON.stringify(image))
  8. }
  9. .clip(false)
复制代码
场景三 滚动列表底部延伸场景

场景形貌

在列表滚动场景中,滚动时内容可与导航条地区重合,滚动到底部时,底部内容需避让导航条。

开发步骤


  • 设置列表组件ListexpandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]),扩展列表底部到安全地区。此时List组件体现地区扩大,滚动时列表内容可在导航条地区体现。
  1. List() {
  2.   // ...
  3. }
  4. .layoutWeight(1)
  5. .scrollBar(BarState.Off)
  6. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
复制代码

  • 将滚动到底部的提示添加在列表项末端,由于设置[expandSafeArea]属性不影响子组件的结构,以是滚动到底部时提示文字默认会避让导航条。
  1. ForEach(getFaqData(), (faq: Faq) => {
  2.   ListItem() {
  3.     this.FaqItem(faq)
  4.   }
  5. }, (faq: Faq) => JSON.stringify(faq))
  6. ListItem() {
  7.   Text($r('app.string.faq_list_all'))
  8.     .width('100%')
  9.     .textAlign(TextAlign.Center)
  10.     .opacity(0.6)
  11.     .padding({ top: 10, bottom: 10 })
  12. }
复制代码
场景四 全屏沉浸式场景

场景形貌

在一些视频播放或启动页的沉浸式页面中,为了更好的观看或操纵体验,通常必要隐蔽状态栏和导航栏。
开发步骤

在页面体现或隐蔽时,利用[Window.setWindowLayoutFullScreen()]方法设置窗口是否为全屏模式,利用[Window.setWindowSystemBarEnable()]方法设置状态栏和导航条显隐。
代码如下:
  1. onShown() {
  2.   this.windowClass.setWindowLayoutFullScreen(true);
  3.   this.windowClass.setWindowSystemBarEnable([]);
  4. }
  5. onHidden() {
  6.   this.windowClass.setWindowLayoutFullScreen(false);
  7.   this.windowClass.setWindowSystemBarEnable(['status', 'navigation']);
  8. }
  9. build() {
  10.   NavDestination() {
  11.     Column() {
  12.       Video({ src: $rawfile('video.mp4') })
  13.         // ...
  14.     }
  15.     .height('100%')
  16.     .width('100%')
  17.   }
  18.   .hideTitleBar(true)
  19.   .onShown(() => this.onShown())
  20.   .onHidden(() => this.onHidden())
  21. }
复制代码
场景五 深色背景下状态栏颜色适配场景

场景形貌

在某些将深色背景延伸到状态栏的沉浸式页面中,必要设置状态栏时间文字、信号图标、电量图标等内容为浅色进行适配,制止状态栏内容不清晰,以此提拔用户的视觉体验。
开发步骤


  • 设置背景图片组件expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]),扩展安全地区到状态栏和导航栏,实现沉浸式效果。
  1. Image(this.getBackGroundImage())
  2.   .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
复制代码

  • 在页面体现或隐蔽时,利用[Window.setWindowSystemBarProperties()]方法设置状态栏内容的颜色。
  1. onShown() {
  2.   this.windowClass.setWindowSystemBarProperties({
  3.     statusBarContentColor: '#FFFFFF'
  4.   });
  5. }
  6. onHidden() {
  7.   this.windowClass.setWindowSystemBarProperties({
  8.     statusBarContentColor: '#000000'
  9.   });
  10. }
  11. build() {
  12.   NavDestination() {
  13.     // ...
  14.   }
  15.   .hideTitleBar(true)
  16.   .onShown(() => this.onShown())
  17.   .onHidden(() => this.onHidden())
  18. }
复制代码
末端

此次 HarmonyOS NEXT 沉浸式页面开发实践,只是探索的开端。未来,技能浪潮将不断奔涌,盼望会有更多的开发者们能以此次经验为基石,在技能海洋中一连破浪前行,利用 HarmonyOS NEXT 的特性创造出更多震撼人心的作品,为鸿蒙世界添砖加瓦。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曹旭辉

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表