鸿蒙UI开发——基于组件安全区方案实现沉浸式界面

1、概 述

本文是接着上篇文章 鸿蒙UI开发——基于全屏方案实现沉浸式界面 的继续讨论。除了全屏方案实现沉浸式界面外,我们还可以使用组件安全区的方案。

当我们没有使用setWindowLayoutFullScreen()接口设置窗口为全屏布局时,默认使用的策略就是组件安全区布局方式。即:

【应用在默认情况下窗口背景绘制范围是全屏,但UI元素被限制在安全区内(自动排除状态栏和导航条)进行布局,来避免界面元素被状态栏和导航条遮盖】

示意图如下:

图片

我们将按业务场景去分析基于组件安全区的沉浸式界面的开发。

2、状态栏和导航条颜色相同场景

针对有些APP,状态栏和导航条颜色可能相同,例如如下效果:

图片

针对这种场景,我们可以通过设置窗口的背景色来实现沉浸式效果,设置方式为:setWindowBackgroundColor() 【将窗口的颜色和应用的颜色设置为一致】

Ability中设置window的背景色代码如下(请注意14行代码):

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';import { window } from '@kit.ArkUI';export default class EntryAbility extends UIAbility {  // ...  onWindowStageCreate(windowStage: window.WindowStage): void {    windowStage.loadContent('pages/Index', (err, data) => {      if (err.code) {        return;      }      // 设置全窗颜色和应用元素颜色一致      windowStage.getMainWindowSync().setWindowBackgroundColor('#008000');    });  }}

组件中的背景色设置代码如下(请注意35行代码):

// xxx.ets@Entry@Componentstruct Example {  build() {    Column() {      Row() {        Text('ROW1').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW2').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW3').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW4').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW5').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW6').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)    }    .width('100%')    .height('100%')    .alignItems(HorizontalAlign.Center)    .justifyContent(FlexAlign.SpaceBetween)    .backgroundColor('#008000')  }}

实现效果如下:

图片

3、状态栏和导航条颜色不同场景

状态栏和导航条颜色不同时,可以使用expandSafeArea属性扩展安全区域属性进行调整。示例代码如下:​​​​​​​

// xxx.ets@Entry@Componentstruct Example {  build() {    Column() {      Row() {        Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')      }      .backgroundColor('#F08080')      // 设置顶部绘制延伸到状态栏      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])      Row() {        Text('ROW2').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW3').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW4').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW5').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')      }      .backgroundColor(Color.Orange)      // 设置底部绘制延伸到导航条      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])    }    .width('100%').height('100%').alignItems(HorizontalAlign.Center)    .backgroundColor('#008000')    .justifyContent(FlexAlign.SpaceBetween)  }}

效果如下:

图片

【扩展安全区域属性原理】

  • 布局阶段按照安全区范围大小进行UI元素布局。

  • 布局完成后查看设置了expandSafeArea的组件边界(不包括margin)是否和安全区边界相交。

  • 如果设置了expandSafeArea的组件和安全区边界相交,根据expandSafeArea传递的属性则进一步扩大组件绘制区域大小覆盖状态栏、导航条这些非安全区域。

  • 上述过程仅改变组件自身绘制大小,不进行二次布局,不影响子节点和兄弟节点的大小和位置。

  • 子节点可以单独设置该属性,只需要自身边界和安全区域重合就可以延伸自身大小至非安全区域内,需要确保父组件未设置clip等裁切属性。

  • 配置expandSafeArea属性组件进行绘制扩展时,需要关注组件不能配置固定宽高尺寸,百分比除外。

4、背景图和视频场景

设置背景图、视频控件大小为安全区域大小并配置expandSafeArea属性。​​​​​​​

// xxx.ets@Entry@Componentstruct SafeAreaExample1 {  build() {    Stack() {      Image($r('app.media.bg'))        .height('100%').width('100%')        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) // 图片组件的绘制区域扩展至状态栏和导航条。    }.height('100%').width('100%')  }}

效果图如下:

图片

5、滚动类场景

场景需求:需要List滚动类组件滚动过程中元素可以和导航条重合,滚动至底部时,元素在导航条上面需要避让。示意图如下:

图片

由于expandSafeArea不改变子节点布局,因此,List等滚动类组件可以调用expandSafeArea,延伸List组件视图窗口大小而不改变ListItem内在布局。实现ListItem在滑动过程中显示在导航条下,但滚动至最后一个时显示在导航条上。

开发示例如下:

step 1 : 配置窗口整体底色​​​​​​​

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';import { window } from '@kit.ArkUI';export default class EntryAbility extends UIAbility {  // ...  onWindowStageCreate(windowStage: window.WindowStage): void {    windowStage.loadContent('pages/Index', (err, data) => {      if (err.code) {        return;      }      windowStage.getMainWindowSync().setWindowBackgroundColor('#DCDCDC'); // 配置窗口整体底色    });  }}

step 2 : 界面代码展示​​​​​​​

// xxx.ets@Entry@Componentstruct ListExample {  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  build() {    Column() {      List({ space: 20, initialIndex: 0 }) {        ForEach(this.arr, (item: number) => {          ListItem() {            Text('' + item)              .width('100%')              .height(100)              .fontSize(16)              .textAlign(TextAlign.Center)              .borderRadius(10)              .backgroundColor(0xFFFFFF)          }        }, (item: string) => item)      }      .listDirection(Axis.Vertical) // 排列方向      .scrollBar(BarState.Off)      .friction(0.6)      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线      .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring      .width('90%')      // List组件的视窗范围扩展至导航条。      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])    }    .width('100%')    .height('100%')    .padding({ top: 15 })  }}

6、底部页签场景

场景需求:页签背景色能够延伸到导航条区域,但页签内部可操作元素需要在导航条之上。

图片

针对底部的页签部分,Navigation组件和Tabs组件默认实现了页签的延伸处理,我们使用时只需要保证Navigation和Tabs组件的底部边界和底部导航条重合即可。

若我们显式调用expandSafeArea接口,则安全区效果由expandSafeArea参数指定。

如果我们没有使用Navigation和Tab组件而是采用自定义方式实现页签的场景,可以针对底部元素设置expandSafeArea属性实现底部元素的背景扩展。

顶部和底部UI元素未设置和设置expandSafeArea属性效果对比如下:

图片

沉浸式实现代码如下:​​​​​​​

// xxx.ets@Entry@Componentstruct VideoCreateComponent {  build() {    Column() {      Row() {        Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')      }      .backgroundColor('#F08080')      // 设置顶部绘制延伸到状态栏      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])      Row() {        Text('ROW2').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW3').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW4').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('ROW5').fontSize(40)      }.backgroundColor(Color.Orange).padding(20)      Row() {        Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')      }      .backgroundColor(Color.Orange)      // 设置底部绘制延伸到导航条      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])    }    .width('100%').height('100%').alignItems(HorizontalAlign.Center)    .justifyContent(FlexAlign.SpaceBetween)    .backgroundColor(Color.Green)  }}

7、图文场景

当状态栏元素和底部导航条元素不同时,无法单纯通过窗口背景色或者背景图组件延伸实现,此时需要对顶部元素和底部元素分别配置expandSafeArea属性,顶部元素配置expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP]),底部元素配置expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.BOTTOM])。

代码如下:​​​​​​​

@Entry@Componentstruct Index {  build() {    Swiper() {      Column() {        Image($r('app.media.start'))          .height('50%').width('100%')          // 设置图片延伸到状态栏          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])        Column() {          Text('HarmonyOS 第一课')            .fontSize(32)            .margin(30)          Text('通过循序渐进的学习路径,无经验和有经验的开发者都可以掌握ArkTS语言声明式开发范式,体验更简洁、更友好的HarmonyOS应用开发旅程。')            .fontSize(20).margin(20)        }.height('50%').width('100%')        .backgroundColor(Color.White)        // 设置文本内容区背景延伸到导航栏        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])      }    }    .width('100%')    .height('100%')    // 关闭Swiper组件默认的裁切效果以便子节点可以绘制在Swiper外。    .clip(false)  }}

实现效果如下:

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/459326.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙学习总结

鸿蒙(HarmonyOS),做为国产自主研发设计的第一个操作系统,从开放测试以来一直备受关注。其纯血鸿蒙版(HarmonyOS NEXT)也于进日发布。过去的一段时间里,我站在一个移动开发者的角度对HarmonyOS进…

【electron8】electron实现“图片”的另存为

注:该列出的代码,都在文章内示例出 1. 另存为按钮事件: const saveAsHandler async () > {const { path, sessionId } recordInfoif(typeof message ! string) return;// 因为我的图片是加密的,所以我需要根据接口返回的路…

着色器的认识

知识了解: 着色器: 顶点着色器: 用来描述顶点的特性,如位置、颜色等,其中,顶点:是指二维或三维空间中的一个点比如交点或者端点。 片元着色器:用来进行逐片元处理操作,比如光照、颜色叠加等&…

如何将原本打开Edge呈现出的360浏览器,更换成原本的Edge页面或者百度等其他页面

每次打开Edge浏览器,都会呈现出360浏览器的页面,很烦。以下将说明如果将呈现出的360浏览器,更换成原本的Edge页面或者百度等其他页面。 1.找到你的控制面板,点击卸载程序。 2. 找到360安全卫士,右键单击更改/卸载。 3…

Android 应用申请 Google MBA权限

Google Case链接:89 > 34810 > 30025 > 155353 > Handheld > MBA Policies 按照指引填写模板 This bug is for the approval of MBAs under [13.2.2 Pregrant permissions policy](https://docs.partner.android.com/gms/policies/domains/mba#mba-…

基于 ThinkPHP+Mysql 灵活用工_灵活用工系统_灵活用工平台

基于 ThinkPHPMysql 灵活用工灵活用工平台灵活用工系统灵活用工小程序灵活用工源码灵活用工系统源码 开发语言 ThinkPHPMysql 源码合作 提供完整源代码 软件界面展示 一、企业管理后台 二、运用管理平台 三、手机端

Web 核心指标优化之 INP 篇

这篇文章是我在公司做 INP 优化经验分享的演讲稿。 大家好,今天我要做的分享是关于 INP 的一些优化经验。 概念 首先,什么叫 INP 呢。 INP 的全称叫 Interaction to Next Pain ,翻译过来就是从交互到下一次绘制的延迟。这是 Google 提出来的…

Footprint Analytics 现已支持 TRON 链上数据分析

我们很高兴地宣布,全球最大的区块链网络之一 TRON(波场)已经成功接入 Footprint Analytics!通过这次集成,开发者、分析师和区块链爱好者们现在可以使用 Footprint 的专业分析工具,深入挖掘 TRON 生态系统的…

考到了PMP证书之后,我的电话被打爆了....

考到了PMP之后,万年不见响的手机竟也开始频繁来call了~🙅 一般是哪些人,会因为什么事来找?本期小赛就给大家讲讲是啥情况~ 一、HR打电话邀请面试 在没有PMP证书的时候,自己投出去的简历往往是石沉大海,杳…

UI设计软件全景:13款工具助力创意实现

选择恰当的UI设计工具对于创建美观且用户体验良好的应用程序界面至关重要。不同的APP功能可能需要不同的界面设计软件,但并非所有工具都需要精通,熟练掌握几个常用的就足够了。以下是13款APP界面设计软件,它们能够为你的团队提供绘制APP界面所…

使用iframe内嵌grafana监控页面

grafana监控大盘被普遍采用,但一个缺点就是一次只能打开一个页面,切换页面很不便,如果能一次同时展示多个页面就好了,如图: 使用tab标签,结合iframe,把各个监控页面全放在一起,可以…

人脸美颜 API 对接说明

本文将介绍一种 人脸美颜 API 对接说明,它可以通过用户上传一张人脸图片(最多能处理一张图片中最大的五张人脸信息),精准定位五官,实现美肤、亮肤、祛痘等美颜功能。 接下来介绍下 人脸美颜 API 的对接说明。 申请流…

【HTML】之基本标签的使用详解

HTML(HyperText Markup Language,超文本标记语言)是构建网页的基础。它不是一种编程语言,而是一种标记语言,用于描述网页的内容和结构。本文将带你了解HTML的基础知识,并通过详细的代码示例和中文注释进行讲…

论文略读:Can We Edit Factual Knowledge by In-Context Learning?

EMNLP 2023 第一个探索in-context learning在语言模型知识编辑方便的效果 传统的知识编辑方法通过在包含特定知识的文本上进行微调来改进 LLMs 随着模型规模的增加,这些基于梯度的方法会带来巨大的计算成本->论文提出了上下文知识编辑(IKE&#xff0…

HarmonyOS第一课——HarmonyOS介绍

HarmonyOS第一课 HarmonyOS介绍 HarmonyOS是新一代的智能终端操作系统(泛终端服务的载体); 智慧互联协同,全场景交互体验; 核心技术理念: 一次开发 多次部署: 预览 可视化开发UI适配 事件交…

51单片机之按键驱动

1.按键简介 按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。开发板上使用的按键及内部简易图如下图所示:   按键管脚两端距离长的表示默认是导通状态,距离短的默认是断开状态, 如果…

如何用示波器测实时时钟信号和主时钟信号

使用示波器测量实时时钟信号(RTC)和主时钟信号(Main Clock Signal)的步骤如下: 1. 准备工作 选择合适的探头:使用高品质的示波器探头,通常10X衰减探头适合大部分情况。校准探头:确…

端口号和ip地址一样吗?区别是什么

在网络通信的世界里,端口号和IP地址是两个不可或缺的概念,它们各自扮演着独特的角色,共同维系着数据在网络中的有序传输。然而,对于许多初学者而言,这两者往往容易被混淆,认为它们是同一事物的不同表述。那…

【Linux】nohup 命令

【Linux】nohup 命令 1. 语法格式2. 实例3. 查找后台进程 nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。 nohup 命令,在默认情况下(非重定向时&#x…

NVR批量管理软件/平台EasyNVR多个NVR同时管理支持UDP和TCP传输协议

随着科技的飞速发展,视频技术已成为现代社会不可或缺的一部分,广泛应用于安防监控、娱乐传播、在线教育、电商直播等多个领域。在这一背景下,NVR管理平台EasyNVR作为一款高效、灵活的视频监控管理系统,正经历着前所未有的发展机遇…