当前位置: 首页 > news >正文

HarmonyOS学习记录4

HarmonyOS学习记录4

本文为个人学习记录,仅供参考,如有错误请指出。本文主要记录应用程序框架基础和ArkUI基础开发。
参考官方文档:
文档1
文档2


UIAbility组件概述

UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。

设计理念
  • 支持应用组件级的跨端迁移和多端协同
  • 支持多设备和多窗口形态
划分原则与建议

UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:

  • 如果开发者希望在任务视图中看到一个任务,建议使用“一个UIAbility+多个页面”的方式,可以避免不必要的资源加载
  • 如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,建议使用多个UIAbility实现不同的功能
    例如,即时通讯类应用中的消息列表与音视频通话采用不同的UIAbility进行开发,既可以方便地切换任务窗口,又可以实现应用的两个任务窗口在一个屏幕上分屏显示
声明配置

注意,为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息。

{"module": {// ..."abilities": [{"name": "EntryAbility", // UIAbility组件的名称"srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility组件的代码路径"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息"icon": "$media:icon", // UIAbility组件的图标"label": "$string:EntryAbility_label", // UIAbility组件的标签"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引// ...}]}
}

UIAbility组件生命周期

UIAbility组件的核心生命周期回调包括onCreate、onForeground、onBackground、onDestroy。作为一种包含UI的应用组件,UIAbility的生命周期不可避免地与WindowStage的生命周期存在关联关系。如下图所示。
在这里插入图片描述

  • onCreate()
    • 在首次创建UIAbility实例时,系统触发onCreate回调。开发者可以在该回调中执行UIAbility整个生命周期中仅发生一次的启动逻辑
  • onWindowStageCreate()
    • UIAbility实例创建完成之后,在进入前台之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate回调,开发者可以在该回调中进行UI加载、WindowStage的事件订阅
    • 在onWindowStageCreate()回调中通过loadContent方法设置应用要加载的页面,并根据需要调用on('windowStageEvent’)方法订阅WindowStage的事件(获焦/失焦、切到前台/切到后台、前台可交互/前台不可交互)
  • onForeground()
    • 在UIAbility切换至前台时且UIAbility的UI可见之前,系统触发onForeground回调。开发者可以在该回调中申请系统需要的资源,或者重新申请在onBackground()中释放的资源。系统回调该方法后,UIAbility实例进入前台状态,即UIAbility实例可以与用户交互的状态。UIAbility实例会一直处于这个状态,直到被某些动作打断(例如屏幕关闭、用户跳转到其他UIAbility)
    • 例如,应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI显示之前,开发者可以在onForeground()回调中开启定位功能,从而获取到当前的位置信息
  • onBackground()
    • 在UIAbility的UI完全不可见之后,系统触发onBackground回调,回调后触发UIAbility实例切换至后台状态。开发者可以在该回调中释放UI不可见时的无用资源,例如停止定位功能,以节省系统的资源消耗
    • onBackground()执行时间较短,无法提供足够的时间做一些耗时动作。请勿在该方法中执行保存用户数据或执行数据库事务等耗时操作
  • onWindowStageWillDestroy()
    • 在UIAbility实例销毁之前,系统触发onWindowStageWillDestroy回调。该回调在WindowStage销毁前执行,此时WindowStage可以使用。开发者可以在该回调用释放通过WindowStage获取的资源、注销WindowStage事件订阅等
  • onWindowStageDestroy()
    • 在UIAbility实例销毁之前,系统触发onWindowStageDestroy回调,开发者可以在该回调中释放UI资源。该回调在WindowStage销毁后执行,此时WindowStage不可以使用
  • onDestroy()
    • 在UIAbility实例销毁之前,系统触发onDestroy回调。该回调是UIAbility接收到的最后一个生命周期回调,开发者可以在onDestroy()回调中进行系统资源的释放、数据的保存等操作
    • 例如,调用terminateSelf方法停止当前UIAbility实例,执行onDestroy()回调,并完成UIAbility实例的销毁
  • onNewWant()
    • 当应用的UIAbility实例已创建,再次调用方法启动该UIAbility实例时,系统触发该UIAbility的onNewWant回调。开发者可以在该回调中更新要加载的资源和数据等,用于后续的UI展示

启动模式

如需修改启动模式,在module.json5配置文件中的launchType字段配置为对应字段即可

{"module": {// ..."abilities": [{"launchType": "singleton",  // 三种启动模式singleton、multition、specified// ...}]}
}
  • singleton(单实例模式)
    • 默认的启动模式,每次调用startAbility方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例
  • multition(多实例模式)
    • multiton启动模式为多实例模式,每次调用startAbility方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例
  • specified(指定实例模式)
    • specified启动模式为指定实例模式,针对一些特殊场景使用,例如,文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例

ArkUI框架

简介
ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发。针对不同的应用场景及技术背景,方舟UI框架提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)。

声明式UI语法

在这里插入图片描述

  • 装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新
  • UI描述:以声明式的方式来描述UI的结构,例如build()方法中的代码块
  • 自定义组件:可复用的UI单元,可组合其他组件,如上述被@Component装饰的struct Hello。
  • 系统组件:ArkUI框架中默认内置的基础和容器组件,可以直接调用,例如示例中的Column、Text、Divider、Button
  • 属性方法:组件可以通过链式调用配置多项属性,如fontSize()、width()、height()、backgroundColor()等
  • 事件方法:组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()

⠀除此之外,ArkTS扩展了多种语法范式来使开发更加便捷:

  • @Builder/@BuilderParam:特殊的封装UI描述的方法,细粒度的封装和复用UI描述
  • @Extend/@Styles:扩展系统组件和封装属性样式,更灵活地组合系统组件
  • stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式
页面和自定义组件的生命周期

被@Entry装饰的组件(页面)的生命周期流程,如下图所示
在这里插入图片描述

router页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:(不推荐使用)

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景
  • onBackPress:当用户点击返回按钮时触发

⠀组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行
  • onDidBuild:组件build()函数执行完成之后回调该接口,开发者可以在这个阶段进行埋点数据上报等不影响实际UI的功能。不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现
  • aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定

组件
  • Image组件
    • 参考文档:组件
  • Text组件
    • 参考文档:同上
  • TextInput组件
    • 参考文档:同上
  • Button组件
    • 参考文档:同上

布局

声明式UI提供了以下10种常见布局
参考文档:布局

  • 线性布局(Row、Column):如果布局内子元素超过1个时,且能够以某种方式线性排列时优先考虑此布局
  • 层叠布局(Stack):组件需要有堆叠效果时优先考虑此布局。层叠布局的堆叠效果不会占用或影响其他同容器内子组件的布局空间。例如Panel作为子组件弹出时将其他组件覆盖更为合理,则优先考虑在外层使用堆叠布局
  • 弹性布局(Flex):弹性布局是与线性布局类似的布局方式。区别在于弹性布局默认能够使子组件压缩或拉伸。在子组件需要计算拉伸或压缩比例时优先使用此布局,可使得多个容器内子组件能有更好的视觉上的填充效果
  • 相对布局(RelativeContainer):相对布局是在二维空间中的布局方式,不需要遵循线性布局的规则,布局方式更为自由。通过在子组件上设置锚点规则(AlignRules)使子组件能够将自己在横轴、纵轴中的位置与容器或容器内其他子组件的位置对齐。设置的锚点规则可以天然支持子元素压缩、拉伸、堆叠或形成多行效果。在页面元素分布复杂或通过线性布局会使容器嵌套层数过深时推荐使用
  • 栅格布局(GridRow、GridCol):栅格是多设备场景下通用的辅助定位工具,可将空间分割为有规律的栅格。栅格不同于网格布局固定的空间划分,可以实现不同设备下不同的布局,空间划分更随心所欲,从而显著降低适配不同屏幕尺寸的设计及开发成本,使得整体设计和开发流程更有秩序和节奏感,同时也保证多设备上应用显示的协调性和一致性,提升用户体验。推荐内容相同但布局不同时使用
  • 媒体查询(@ohos.mediaquery):媒体查询可根据不同设备类型或同设备不同状态修改应用的样式。例如根据设备和应用的不同属性信息设计不同的布局,以及屏幕发生动态改变时更新应用的页面布局
  • 列表(List):使用列表可以高效地显示结构化、可滚动的信息。在ArkUI中,列表具有垂直和水平布局能力和自适应交叉轴方向上排列个数的布局能力,超出屏幕时可以滚动。列表适合用于呈现同类数据类型或数据类型集,例如图片和文本
    • 接口:List(value?:{space?:number | string,initialIndex?:number,scroller?: Scroller})
    • 参数1:space设置子组件主轴方向的间隔
    • 参数2:initialIndex设置当前List初次加载时,视口起始位置显示的item的索引值,默认为0
    • 参数3:scroller设置可滚动组件的控制器
      • 1.导入对象:let scroller: Scroller = new Scroller();
      • 2.导入对象之后可调用scroller相关方法:
        • scrollTo:滑动到指定位置
        • scrollEdge:滚动到容器边缘
        • scrollBy:滑动指定距离
    • 部分属性:
      • listDirection:设置List组件排列方向
      • lanes:设置List组件的布局列数或行数
      • divider:设置ListItem分割线样式,默认无分割线
      • scrollBar:设置滚动条状态
    • 参考文档:列表
  • 网格(Grid):网格布局具有较强的页面均分能力、子元素占比控制能力。网格布局可以控制元素所占的网格数量、设置子元素横跨几行或者几列,当网格容器尺寸发生变化时,所有子元素以及间距等比例调整。推荐在需要按照固定比例或者均匀分配空间的布局场景下使用,例如计算器、相册、日历等
    • 参考文档:网格
  • 轮播(Swiper):轮播组件通常用于实现广告轮播、图片预览等
    • 接口:Swiper(controller?:SwiperController)
    • 参数:controller给组件绑定一个控制器,用来控制组件翻页
      • 1.导入对象:let controller: SwiperController = new SwiperController();
      • 2.导入对象之后可调用的相关方法:
        • showNext:翻至下一页
        • showPrevious:翻至上一页
        • changeIndex:翻至指定页面
    • 参考文档: 轮播图
  • 选项卡(Tabs):选项卡可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量
    • 接口:Tabs(value:{barPosition?:BarPosition,index?:number,controller?:TabsController})
    • 参数1:barPosition设置Tabs的页签位置
    • 参数2:index设置初始页签索引
    • 参数3:controller设置Tabs控制器,用于控制Tabs组件进行页签切换
    • 参考文档:选项卡

接下来可以运用上述提到的布局编写一些页面

遇到的问题
  • 关于foreach的使用,这里简单放一个不完整的代码,用于展示foreach的使用。可以把foreach理解成for循环函数,但是其中循环的“参数”为其中设置的组件,对这个函数的理解需要运用到箭头函数(Lambda函数)的知识点。foreach函数有三个参数可以填,其中前两个参数必填,第三个参数可选填,第一个参数为arrry类型的数据源;第二个参数,后面括号以及=>即箭头函数,也可以理解为匿名函数,括号中的数据即为这个匿名函数的回调参数,接收到resource类型的img数据之后,会被运用到后面的image组件中,以此类推,遍历array数组中的所有元素,完成循环;第三个参数(下面的案例中没有设置此参数),官方称作元素的唯一标识,这个第一次遇到的时候有点无法理解,然后我就按照官方的文档设置了这个参数,然后在填入模拟数据时发现,当我填入的数据相同时,比如我填入三条相同内容的数据,在编译时不会报错且只会显示一条数据,在查看log时能够明显看到有三条数据,但是在界面中只能看到一条,最后再去查看官方文档时才发现问题,就是因为一开始不懂,设置了foreach的第三个参数,这会给每个数据打一个标签,以保证数据的唯一性,如前面所说,我输入的数据内容都是相同的,自然被归为同一个标签,结果就是在界面中只会显示一条数据,所以默认情况下,使用foreach时可以不用设置第三个参数,或许在需要过滤相同数据时才会使用到此参数
Swiper(this.TopSwiperController) {ForEach(mainViewModel.getSwiperImages(), (img: Resource) => {Image(img).width('95%').objectFit(ImageFit.Auto)})
}
.loop(false)
.width('95%')
.height(220)
.margin({ bottom: 10 })
http://www.dtcms.com/a/273134.html

相关文章:

  • 基于U-net的高阶心音信号去噪系统设计与实现
  • SSE方式调用php,不是直接 post,
  • 【C++基础语法】
  • STM32F103之ModBus\RS232\RS422\RS485
  • 瑞幸X多邻国“疯感”营销:以情感共鸣取代硬广触达
  • Qt开发:QtConcurrent介绍和使用
  • Python正则表达式实战指南
  • 深度学习13(经典卷积网络结构+卷积网络结构优化)
  • J1939协议
  • 个体户核定多地暂停,将不再享受核定征收?
  • 人工智能-基础篇-29-什么是低代码平台?
  • 大数据学习6:Sqoop数据迁移工具
  • ArcGIS 打开 nc 降雨量文件
  • MinerU2将PDF转成md文件,并分拣图片
  • TB6612电机驱动
  • [注解: @ComponentScan]-原理分析
  • Cloudflare 发布容器服务公测版:边缘计算新时代来临?
  • 职坐标:嵌入式AI边缘计算实战
  • React 实现五子棋人机对战小游戏
  • FFmpeg Windows安装
  • 定位模拟的详细步骤
  • vue3使用mermaid生成图表,并可编辑
  • 数学建模:多目标规划:ε约束法、 理想点法
  • 【大模型推理论文阅读】Enhancing Latent Computation in Transformerswith Latent Tokens
  • pharokka phold--快速噬菌体注释工具
  • 深入了解 Vim 编辑器:从入门到精通
  • MySQL高级特性全面解析:约束、表关系、多表查询与事务
  • 深入剖析C++ RPC框架原理:有栈协程与分布式系统设计
  • 技术学习_检索增强生成(RAG)
  • QT数据交互全解析:JSON处理与HTTP通信