当前位置:   article > 正文

OpenHarmony开发实战:视频应用(ArkTS)_arkts backgroundcolor

arkts backgroundcolor

随着智能设备类型的不断丰富,用户可以在不同的设备上享受同样的服务,但由于设备形态不尽相同,开发者往往需要针对具体设备修改或重构代码,以实现功能完整性和界面美观性的统一。OpenHarmony为开发者提供了“一次开发,多端部署”的系统能力,让开发者可以基于一次开发,快速构建不同类型终端上的应用,降低开发成本,提高开发效率。

本篇Codelab基于“一次开发,多端部署”提供的自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。通过三层工程结构尽可能复用了部分代码,并根据设备尺寸的区别设计了对应的页面以兼顾美观和易用。应用被打开时会根据具体的设备形态显示对应的UI界面,其中RK3568开发板的首页效果如图所示:

相关概念

  • 一次开发,多端部署:指一套代码工程,一次开发上架,多端按需部署,目标是支撑开发者高效地开发支持多种终端设备形态的应用。
  • 自适应布局:当外部容器大小发生变化时,元素可以根据相对关系自动变化以适应外部容器变化的布局能力。相对关系如占比、固定宽高比、显示优先级等。当前自适应布局能力有7种:拉伸能力、均分能力、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。自适应布局能力可以实现界面显示随外部容器大小连续变化。
  • 响应式布局:当外部容器大小发生变化时,元素可以根据断点、栅格或特定的特征(如屏幕方向、窗口宽高等)自动变化以适应外部容器变化的布局能力。当前响应式布局能力有3种:断点、媒体查询、栅格布局。
  • GridRow:栅格容器组件,仅可以和栅格子组件(GridCol)在栅格布局场景中使用。
  • GridCol:栅格子组件,必须作为栅格容器组件(GridRow)的子组件使用。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

  2. 搭建烧录环境。

    1. 完成DevEco Device Tool的安装
    2. 完成RK3568开发板的烧录
  3. 搭建开发环境。

    1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用真机进行调测

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。

“一次开发,多端部署”推荐使用三层目录的工程结构来管理工程,上层目录包括common、features和product,common为公共特性目录,存放不同形态设备公用的类和常量,features为功能模块目录,存放应用的各个功能模块,product为产品层目录,存放不同形态设备范类代码。本Codelab不涉及功能特性,因此只存在common、product两个分层。

  1. ├──common // 公共能力层
  2. │ ├──src/main/ets
  3. │ │ ├──constants
  4. │ │ │ └──CommonConstants.ets // 公共常量类
  5. │ │ ├──utils
  6. │ │ │ └──BreakpointSystem.ets // 断点工具类
  7. │ │ └──viewmodel // 资源类接口
  8. │ │ ├──BottomTabsItem.ets
  9. │ │ ├──DriveTabsItem.ets
  10. │ │ ├──FindTabsItem.ets
  11. │ │ ├──HomeTabsItem.ets
  12. │ │ └──MineTabsItem.ets
  13. │ └──src/main/resources // 资源文件夹
  14. └──product // 产品定制层
  15. ├──default/src/main/ets // 支持手机(含折叠屏)、平板
  16. │ ├──entryability
  17. │ │ └──EntryAbility.ts // 程序入口类
  18. │ ├──pages
  19. │ │ └──MainPage.ets // 主页面
  20. │ ├──view
  21. │ │ ├──BottomTabsComponent.ets // 底部页签组件
  22. │ │ ├──DriveTabsComponent.ets // 云盘页组件
  23. │ │ ├──FindTabsComponent.ets // 发现页组件
  24. │ │ ├──HomeTabsComponent.ets // 首页组件
  25. │ │ ├──LeftTabsComponent.ets // 侧边栏组件
  26. │ │ ├──MineTabsComponent.ets // 个人页组件
  27. │ │ ├──RecentlyPlayedComponent.ets // “最近播放”列表
  28. │ │ └──RecommendComponent.ets // “为你推荐”列表
  29. │ └──viewmodel
  30. │ ├──BottomTabsModel.ets // 底部页签model
  31. │ ├──DriveTabsModel.ets // 云盘页model
  32. │ ├──FindTabsModel.ets // 发现页model
  33. │ ├──HomeTabsModel.ets // 首页model
  34. │ └──MineTabsModel.ets // 个人页model
  35. └──default/src/main/resources // 资源文件夹

主页面框架设计

为了操作便捷和充分利用不同形态设备的屏幕空间,按屏幕宽度的大小将设备划分为3类:

  • sm:320vp<=width<520vp,典型设备为手机。
  • md:520vp<=width<840vp,典型设备为折叠屏。
  • lg:840vp<=width,典型设备为平板或PC。

根据用户使用场景,当操作设备尺寸为sm或md时,一般为竖向使用,此时用于切换应用页面的页签栏适合置于底部。当操作设备尺寸为lg时,一般为横向使用,此时页签栏适合置于左侧。

  1. // MainPage.ets
  2. @Entry
  3. @Component
  4. struct MainPage {
  5. ...
  6. build() {
  7. SideBarContainer(SideBarContainerType.Embed) {
  8. LeftTabs({ bottomTabIndex: $bottomTabIndex }); // 侧边栏
  9. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) {
  10. Tabs({ barPosition: BarPosition.End, index: 0, controller: this.controller }) {
  11. ... // 页面内容
  12. }
  13. if (this.currentBreakpoint !== Const.LG) {
  14. BottomTabs({ bottomTabIndex: $bottomTabIndex }) // 底部栏,当屏幕尺寸不为"lg"时显示
  15. }
  16. }
  17. .width(Const.FULL_SIZE)
  18. .backgroundColor($r('app.color.background_color'))
  19. }
  20. .showSideBar(this.currentBreakpoint === Const.LG) // 当屏幕尺寸为"lg"时显示侧边栏
  21. .showControlButton(false)
  22. .sideBarWidth(Const.SIDEBAR_WIDTH)
  23. .maxSideBarWidth(Const.SIDEBAR_WIDTH_MAX)
  24. .minSideBarWidth(Const.SIDEBAR_WIDTH_MIN)
  25. }
  26. }

各页面代码实现

首页

首页显示轮播图和“最近播放”、“为你推荐”两个列表,轮播图根据屏幕尺寸的区别,有显示数量的不同(sm为1,md为2,lg为3),列表使用具备自适应布局能力的List组件。

  1. // HomeTabsComponent.ets
  2. @Component
  3. export struct HomeTabs {
  4. @Link currentBreakpoint: string;
  5. private scroller: Scroller = new Scroller();
  6. build() {
  7. Scroll(this.scroller) {
  8. GridRow({
  9. // 设置sm、md和lg的布局列数分别为4812
  10. columns: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 },
  11. gutter: { x: $r('app.float.gutter_home') },
  12. breakpoints: { value: [Const.BREAKPOINTS_SM, Const.BREAKPOINTS_MD, Const.BREAKPOINTS_LG] }
  13. }) {
  14. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  15. ... // 标题
  16. }
  17. .height($r('app.float.title_height'))
  18. .margin({ bottom: $r('app.float.home_margin1') })
  19. // 搜索栏在sm、md下占满全部列,在lg下占8
  20. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_8 } }) {
  21. ... // 搜索栏
  22. }
  23. .height($r('app.float.home_grid_height1'))
  24. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  25. Swiper() {
  26. ...
  27. }
  28. .height($r('app.float.home_swiper_height'))
  29. .itemSpace(Const.ITEM_SPACE)
  30. // 根据屏幕尺寸大小选择不同的轮播图数量
  31. .displayCount(this.currentBreakpoint === Const.LG ?
  32. Const.NUM_3 : (this.currentBreakpoint === Const.MD ? Const.NUM_2 : Const.NUM_1))
  33. }
  34. .height($r('app.float.home_grid_height2'))
  35. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  36. ... // ”最近播放”列表
  37. }
  38. .height($r('app.float.home_grid_height3'))
  39. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  40. ... // ”为你推荐”列表
  41. }
  42. .height($r('app.float.home_column_height'))
  43. }
  44. .height(Const.FULL_SIZE)
  45. }
  46. ...
  47. }
  48. }

发现页

发现页使用栅格布局实现“一次开发,多端部署”能力,把sm设置为4列,md设置为8列,lg设置为12列。热播榜单在不同设备尺寸上分别占据4列、6列和8列。

  1. // FindTabsComponent.ets
  2. @Component
  3. export struct FindTabs {
  4. private scroller: Scroller = new Scroller();
  5. build() {
  6. Scroll(this.scroller) {
  7. GridRow({
  8. // 设置sm、md和lg的布局列数分别为4812
  9. columns: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 },
  10. gutter: { x: $r('app.float.gutter_find') },
  11. breakpoints: { value: [Const.BREAKPOINTS_SM, Const.BREAKPOINTS_MD, Const.BREAKPOINTS_LG] }
  12. }) {
  13. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  14. ... // 标题
  15. }
  16. .height($r('app.float.title_height'))
  17. LazyForEach(new FindDataSource(FindTabsList), (item: FindTabsItem) => {
  18. // 设置热播榜单在sm、md和lg上分别占据468列,并且设置offset属性保证在不同设备形态上都能保持居中
  19. GridCol({
  20. span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_6, lg: Const.GRID_8 },
  21. offset: {
  22. md: FindTabsList.indexOf(item) === Const.OFFSET_0 ? Const.OFFSET_1 : Const.OFFSET_2,
  23. lg: FindTabsList.indexOf(item) === Const.OFFSET_0 ? Const.OFFSET_2 : Const.OFFSET_4
  24. }
  25. }) {
  26. ... // 榜单内容
  27. }
  28. }, (item: FindTabsItem) => JSON.stringify(item))
  29. }
  30. }
  31. ...
  32. }
  33. }

RK3568开发板上发现页的实际效果如图所示:

云盘页

云盘页的栅格划分和发现页相同,但是每个子组件在所有屏幕尺寸上都只占据2列。

  1. // DriveTabsComponent.ets
  2. @Component
  3. export struct DriveTabs {
  4. private scroller: Scroller = new Scroller();
  5. build() {
  6. Scroll(this.scroller) {
  7. GridRow({
  8. // 设置sm、md和lg的布局列数分别为4812
  9. columns: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 },
  10. gutter: { x : $r('app.float.gutter_drive') },
  11. breakpoints: { value: [Const.BREAKPOINTS_SM, Const.BREAKPOINTS_MD, Const.BREAKPOINTS_LG] }
  12. }) {
  13. GridCol({ span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 } }) {
  14. ... // 标题
  15. }
  16. .height($r('app.float.title_height'))
  17. ForEach(DriveList, (item: DriveTabsItem) => {
  18. // 设置云盘内容在sm、md和lg上均占据2
  19. GridCol({ span: { xs: Const.NUM_2, sm: Const.NUM_2, md: Const.NUM_2, lg: Const.NUM_2 } }) {
  20. ... // 云盘内容
  21. }
  22. }, (item: DriveTabsItem) => JSON.stringify(item))
  23. }
  24. }
  25. ...
  26. }
  27. }

RK3568开发板上云盘页的实际效果如图所示:

个人页

个人页的栅格划分仍然和发现页相同,但子组件在sm、md形态下占满全部列,在lg形态下只占据8列。

  1. // MineTabsComponent.ets
  2. @Component
  3. export struct MineTabs {
  4. private scroller: Scroller = new Scroller();
  5. build() {
  6. Scroll(this.scroller) {
  7. GridRow({
  8. // 设置sm、md和lg的布局列数分别为4812
  9. columns: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_12 },
  10. gutter: { x: $r('app.float.gutter_mine') },
  11. breakpoints: { value: [Const.BREAKPOINTS_SM, Const.BREAKPOINTS_MD, Const.BREAKPOINTS_LG] }
  12. }) {
  13. // 设置个人页在sm和md上占满全部列,在lg上占8列,为保证居中在lg上设置offset为2
  14. GridCol({
  15. span: { xs: Const.GRID_4, sm: Const.GRID_4, md: Const.GRID_8, lg: Const.GRID_8 },
  16. offset: { lg: Const.OFFSET_2 }
  17. }) {
  18. ... // 个人页内容
  19. }
  20. }
  21. .height(Const.FULL_SIZE)
  22. .backgroundColor($r('app.color.mine_background_color'))
  23. }
  24. ...
  25. }
  26. }

RK3568开发板上个人页的实际效果如图所示:

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

 获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

 有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/998910
推荐阅读
相关标签
  

闽ICP备14008679号