0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于eTS的HamronyOS应用开发

HarmonyOS开发者 来源:HarmonyOS开发者 作者:HarmonyOS开发者 2022-07-15 09:20 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

随着HarmonyOS 3.0 Beta版的发布,API Version 8新增了大批JS/eTS API接口,相信很多开发者已经迫不及待想体验基于eTS的HamronyOS应用开发。本期Codelab,我们将基于API Version 8实现一个HarmonyOS课程类应用,帮助大家学习eTS的声明式UI描述、循环渲染、状态数据管理等机制,体验基于eTS的极简高效开发。

一、整体介绍

在课程类应用界面中,左侧为课程分类导航栏,右侧为各个类别的课程内容。当用户上下滑动右侧课程内容时,左侧导航栏会跳转至对应的课程分类。当用户点击左侧导航栏的课程分类时,会高亮显示点击的内容,且右侧课程内容会跳转至对应类别的课程列表。

那么如何基于eTS高效实现这样一个HarmonyOS课程类应用?下面我们将从声明式UI描述、循环渲染数据、状态数据管理三个维度来解析。

1. 声明式UI描述

界面布局是UI界面的骨架,决定了应用界面的交互和视觉风格。本示例中我们将通过eTS的一系列基础组件以声明式方式进行组合和扩展,并采用接近自然语义的编程语法直观地描述UI界面,包括参数构造配置、属性配置、事件配置以及子组件配置等。

相较于基于Java的命令式开发,eTS采用更接近自然语义的声明式编程语法,让开发者可以更直观地描述UI界面,有效地降低了开发者的上手成本,极大程度地提升了UI界面的构建效率,实现极简高效开发。

2. 循环渲染数据

数据模型是UI界面的肉体,描述了界面中数据的静态特征、动态行为和约束条件。本示例中我们将通过eTS直观地定义界面中各个模块的数据模型,包含名称、标识、图片链接等,并根据数据模型写入对应的数据。最后使用eTS提供的循环渲染机制(ForEach)将写入的数据循环渲染至对应的界面中。

相较于基于Java的命令式开发,eTS在渲染数据时UI的更新不需要开发者使用代码主动刷新,而是交给框架层自动处理,开发者不必关心框架如何实现UI绘制和渲染,实现界面数据的高效渲染。

3. 状态数据管理

联动效果是UI界面的灵魂,实现了界面中布局与数据的动态交互,本示例中我们将使用eTS提供的状态数据管理机制通过装饰组件拥有的状态属性,当装饰的变量更改时,组件会重新渲染更新UI界面数据,从而实现联动效果。

相较于基于Java的命令式开发,eTS通过功能不同的装饰器给开发者提供了清晰的页面更新渲染流程和管道。开发者要做的就是定义数据与UI的映射关系,后面只需要通过状态装饰器监听数据的状态,UI即可自动刷新,这极大地减轻了程序员对UI的维护工作。

以上就是实现课程类应用的核心原理,下面我们将为大家带来各部分的具体实现。

二、搭建界面布局

eTS提供了多种布局方式,不仅保留了经典的弹性布局能力,也提供了列表、宫格、栅格布局和适应多分辨率场景开发的原子布局能力。如图1所示,本示例中整体布局使用Row沿水平方向布局容器,并设置背景颜色为白色,Row内部嵌套Scroll及List容器分别作为应用界面的导航栏布局和课程内容布局,下面我们将为你一一道来。 7f92ac6e-03db-11ed-ba43-dac502259ad0.png 图1 整体布局

1. 导航栏布局

应用界面的导航栏使用可滚动的容器组件Scroll来实现,Scroll内嵌Text组件用于显示“课程分类”名称,如图2所示: 7fa7daf8-03db-11ed-ba43-dac502259ad0.png

图2 导航栏布局

Scroll容器必须内置一个子组件,我们使用了垂直方向的布局容器Column,并设置填充高度为height('100%')。“课程分类”名称使用Text组件实现,并设置文字颜色为fontColor(0x696969)、文字大小为fontSize(16)、文字对齐方式为textAlign(TextAlign.Center)居中显示、高度为height(60)、宽度为width('100%')。

相关代码如下:

Scroll() {  Column() {    ForEach(this.tabArray.map((item1, index1) => {      return { index: index1, data: item1 };    }), item => {      Text(item.data.superName)        .fontColor(0x696969)        .backgroundColor(this.index == item.index ? 0xffffff : null)        .fontSize(16)        .width('100%')        .height(60)        .textAlign(TextAlign.Center)        .onClick(() => {          if (this.index != item.index) {            this.index = item.index            this.scroller.scrollToIndex(item.data.position)          }        })    }, item => '' + item.data)  }.height('100%')}.width(100).height('100%').backgroundColor(0xdddddd).scrollBar(BarState.Off)

(左右滑动,查看更多)

2. 课程内容布局

应用的课程内容部分的布局使用List列表容器来实现,并使用ForEach循环渲染listArray(课程内容)数据,如图3所示,课程内容布局包含头部和课程信息两部分(头部和左边的导航栏对应),下面我们将分别介绍头部及课程信息的布局的实现。 7fb1f984-03db-11ed-ba43-dac502259ad0.png

图3 课程内容布局

(1) 头部布局

头部使用Text组件实现,并设置了文字颜色为fontColor(0x696969)、文字大小为fontSize(20)、高度为height(40)、宽度为width('100%')填充、内边距为padding({ left: 10 })、背景颜色为backgroundColor(0xefefef)。同时,头部的ListItem设置了sticky(Sticky.Normal)属性,使其滑动到顶部时可以呈现固定的效果。代码如下:

if (item.tag) {  ListItem() {    Text(item.courseName)      .fontColor(0x696969)      .fontSize(20)      .height(40)      .width('100%')      .padding({ left: 10 })      .backgroundColor(0xefefef)  }.sticky(Sticky.Normal)

(左右滑动,查看更多)

(2) 课程信息布局

课程信息部分使用Stack堆叠容器,高度设置为height(120),设置子组件在容器内的对齐方式为Alignment.TopStart。Stack组件内嵌Image、Text、Divider组件,用于呈现课程图片、课程标题、课程价格及分割线等信息。具体如下:

●课程的图片使用Image组件呈现,设置宽度为width(130),高度为height(100),图片的缩放类型为objectFit(ImageFit.Fill),使图片填充满组件,并设置左边、顶部边距均10,使其组件居中对齐。代码如下:

Image(item.imageUrl)  .objectFit(ImageFit.Cover)  .width(130)  .height(100)  .margin({ left: 10, top: 10 })
(左右滑动,查看更多)

●课程名称使用Text组件,设置文字颜色为fontColor(0x363636)、文字大小为fontSize(14),最大显示行数为maxLines(2)两行,文本超长时的显示方式为TextOverflow.Clip,意为进行裁剪显示。代码如下:

Text(item.courseName)  .fontColor(0x363636)  .fontSize(14)  .margin({ left: 150, top: 12 })  .maxLines(2)  .textOverflow({ overflow: TextOverflow.Clip })

(左右滑动,查看更多)

●课程的价格使用Text组件,设置文字颜色为fontColor(0xff6600)、文字大小为fontSize(24),并使用了绝对定位position({ x: 0, y: '100%' })先让组件显示在Stack容器最底部的外边界下,然后使用锚点定位markAnchor({ x: 0, y: '100%' })使组件以自身高度向上偏移,让组件显示在Stack容器最底部。代码如下:

Text(item.price == 0 ? '免费' : '¥' + item.price)  .fontColor(0xff6600)  .fontSize(24)  .position({ x: 0, y: '100%' })  .markAnchor({ x: 0, y: '100%' })  .margin({ bottom: 18, left: 150 })
(左右滑动,查看更多)

●分割线使用Divider组件实现,并设置了分割线颜色为color(0xefefef)、分割线宽度为strokeWidth(0.7)、左右边距margin({ left: 10, right: 10 })均为10,并使用绝对定位position({ x: 0, y: '100%' })和锚点定位markAnchor({ x: 0, y: '100%' })使分割线呈现在Stack容器最底部。代码如下:

Divider()  .margin({ left: 10, right: 10 })  .color(0xefefef)  .strokeWidth(0.7)  .position({ x: 0, y: '100%' })  .markAnchor({ x: 0, y: '100%' })

(左右滑动,查看更多)

至此,我们已经实现了界面布局,此时界面只是一个没有任何内容的骨架。接下来我们将为应用界面添加数据模型。

三、构建数据模型

本章节我们将为大家介绍本示例中数据模型的定义、数据的预置以及数据的加载。

1. 定义数据模型

本示例需定义两个数据模型,分别是应用界面中左侧导航栏的“课程分类”和右侧的“课程内容”。其中:

●导航栏“课程分类”定义了名称(superName)和位置(position)属性。数据模型定义如下:

export class TabItem {  position: number; // 点击该分类时课程内容滑动到的位置  superName: string; // 课程分类标题

  constructor(position: number, superName: string) {    this.position = position;    this.superName = superName;  }}
(左右滑动,查看更多)

●“课程内容”定义了课程的名称(courseName)、课程的图片地址(imageUrl)、课程的价格(price)、判断是否为此类别课程头部的变量(tag)、课程所对应课程类别的索引位置(index),数据模型定义如下:

export class CourseItem {  tag: boolean; // 是否此类别课程的头部  index: number; // 课程所对应课程类别的索引位置  courseName: string; // 课程名称  imageUrl: string; // 图片地址price:number;//价格  constructor(tag: boolean, index: number, courseName: string, imageUrl: string, price: number) {    this.tag = tag;    this.index = index;    this.courseName = courseName;    this.imageUrl = imageUrl;    this.price = price;  }}

(左右滑动,查看更多)

2. 预置数据

在entry/src/main/ets/MainAbility/Model.ets文件中,放入准备好的模拟数据,其中,superId是课程分类的唯一标识、id是课程内容的唯一标识。格式如下:

const LinkData: any[] = [  {     "superId": 1,     "superName": "热门课程",     "id": 1,     "courseName": "应用市场介绍",     "imageUrl": "/image/image1.jpg",     "price": 0   }, {    "superId": 1,    "superName": "热门课程",    "id": 2,    "courseName": "上架流程",    "imageUrl": "/image/image2.jpg",    "price": 100  },  ... ]
(左右滑动,查看更多)

3. 加载数据更新UI

本章节将介绍如何加载本地构造的模拟数据并呈现到界面。

(1) 加载数据

在index.ets文件中,通过getLinkData()获取预置数据。

aboutToAppear() {  // 延时数据加载  setTimeout(() => {    let linkDataItem = getLinkData();    this.tabArray = linkDataItem.tabArray;    this.listArray = linkDataItem.listArray;    this.requestSuccess = true;  }, 2000)}

(左右滑动,查看更多)

(2) 渲染

●导航栏使用ForEach循环渲染tabArray(课程分类)数据。这里的ForEach的第一个参数需要使用数组的map()方法遍历。代码如下:

let superId: number = 0model.forEach((item) => {  if (superId != item.superId) {    let tabItem = new TabItem(this.listArray.length, item.superName);    this.tabArray.push(tabItem)

    let courseItem = new CourseItem(true, this.tabArray.length - 1, item.superName, '', 0);    this.listArray.push(courseItem)  }})
(左右滑动,查看更多)

●课程内容使用ForEach循环渲染listArray(课程内容)数据。代码如下:

ForEach(this.listArray, item => {  if (item.tag) {    ListItem() {    ......    }.sticky(Sticky.Normal)  } else {    ListItem() {      Stack({ alignContent: Alignment.TopStart }) {      ......      }.height(120)    }  }}, item => '' + item)
(左右滑动,查看更多)

通过上文的介绍,我们已经实现了应用界面的布局以及界面数据的呈现,此时界面就像没有灵魂的躯壳。下面我们将为大家介绍应用中联动效果的实现。

四、实现界面联动

本示例中的联动效果包括导航栏高亮显示、滑动课程内容对应导航栏变化、点击导航栏课程分类跳转到对应课程内容,下面我们将一一道来。

7fc0f9f2-03db-11ed-ba43-dac502259ad0.gif

1. 导航栏高亮显示

实现导航栏高亮显示,主要通过@State装饰器监听导航栏课程分类的索引值的状态变化,当用户滑动课程内容或点击导航栏,对应课程分类的索引值发生变化,此时将调用build方法进行UI刷新,从而实现导航栏背景色的修改。相关代码如下:

@State index: number= 0; // 导航栏课程分类的索引Text(item.data.superName)  .backgroundColor(this.index == item.index ? 0xffffff : null)

2. 右边滑动,左边变化

滑动右边课程内容,对应左边导航栏变化,主要通过onScrollIndex()事件来判断当前课程内容所属的课程分类,当用户滑动课程内容时,对应课程内容的索引值发生变化,导航栏的课程分类的索引值也随之变化。相关代码如下:

private scroller: Scroller = new Scroller()List({ scroller: this.scroller }) {  ......  }.onScrollIndex((firstIndex: number) => {  if (this.index != this.listArray[firstIndex].index) {    this.index = this.listArray[firstIndex].index  }})

3. 左边点击,右边跳转

点击左边导航栏跳转到对应课程内容,主要通过onClick()事件监听用户点击,当用户点击导航栏,scrollToIndex()方法会根据点击的导航栏课程分类的索引值跳转到对应的课程内容界面。相关代码如下:

Text(item.data.superName)  .onClick(() => {    if (this.index != item.index) {      this.index = item.index      this.scroller.scrollToIndex(item.data.position)    }  })

以上就是本期全部内容,通过本期Codelab的学习,相信你已经掌握了eTS的声明式UI描述、循环渲染、状态数据管理等机制,赶快趁热打铁,开发更多有趣的应用吧!

原文标题:基于eTS高效开发HarmonyOS课程类应用

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7314

    浏览量

    93938
  • API接口
    +关注

    关注

    1

    文章

    108

    浏览量

    11176
  • HarmonyOS
    +关注

    关注

    80

    文章

    2146

    浏览量

    35536

原文标题:基于eTS高效开发HarmonyOS课程类应用

文章出处:【微信号:HarmonyOS_Dev,微信公众号:HarmonyOS开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    HarmonyOSAI编程万能卡片生成(二)

    后台、使用message事件刷新卡片内容。 目录结构 在module > src > main > ets 路径下, formcommon目录用于存放生成卡片
    发表于 09-09 16:10

    中国中车ETS3动车组在马来西亚启用

    近日,由中国中车集团旗下中车株机公司研制的ETS3动车组从吉隆坡车站启程,驶往柔佛居銮,正式在马来西亚启用,标志着中马两国在轨道交通领域的合作迈上新台阶,成为中马友谊持续深化的重要见证。
    的头像 发表于 08-27 13:44 537次阅读

    【汇思博SEEK100开发板试用体验】3/第一次使用OpenHarmony

    本分享贴,聚焦第一次上手的时候,可能出现的一些问题,希望对其他小伙伴也有帮助。 ​​一、创建首个OpenHarmony工程​​ ​​选择开发范式​​ ​​声明式开发eTS)​​:主流推荐,高性能
    发表于 08-20 22:21

    【汇思博SEEK100开发板试用体验】开发环境安装配置

    src/main/ets/pages/Index.ets 点击右侧​​Preview​​按钮 观察模拟器是否正常渲染界面 ​​开发板烧录验证​​ Type-C连接开发板与主机 IDE识
    发表于 08-20 21:43

    【M-K1HSE开发板免费体验】M-K1HSE开发板构建HELLO WORLD页面

    Project来创建一个新工程。 2)选择Application应用开发(,选择模板“[OpenHarmony]Empty Ability”,点击Next进行下一步配置 3)进入配置工程界面,修改一下
    发表于 07-15 04:31

    【HarmonyOS 5】VisionKit人脸活体检测详解

    检测是什么? VisionKit是HamronyOS提供的场景化视觉服务工具包。 华为将常见的解决方案,通常需要三方应用使用SDK进行集成。华为以Kit的形式集成在HarmoyOS系统中,方便三方应用快速开发和赋能
    的头像 发表于 06-21 11:52 628次阅读
    【HarmonyOS 5】VisionKit人脸活体检测详解

    ArkUI-X在Android平台动态化开发指南

    本文介绍如何在Android平台进行ArkUI-X动态化开发,包括动态化目录规则及约束。 适用场景 动态化主要包括两个典型场景: 场景1:框架动态化,为了降低应用ROM体积占用,及满足动态升级框架
    发表于 06-15 23:33

    ArkUI-x跨平台Bridge最佳实践

    ,影响开发效率和代码整齐程度,所以可以考虑在Interactive类的平台差异化处,直接进行动态import ets文件的处理,处理完成后,文件内使用HMS API的地方无需再增加动态import API
    发表于 06-10 23:06

    如何将一个FA模型开发的声明式范式应用切换到Stage模型

    模型切换概述 本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型,您需要完成如下动作: 工程切换:新建一个Stage模型的应用工程。 配置文件切换:config.json切换
    发表于 06-04 06:22

    鸿蒙5开发宝藏案例分享---一多断点开发实践

    ?【鸿蒙开发实战进阶】六大核心案例深度拆解,带你玩转多端适配! ?** 案例4:动态网格布局(电商商品列表)** 应用场景 :手机/平板商品展示差异痛点分析 :手机单列→平板多列,需智能计算展示数量
    发表于 06-03 11:59

    鸿蒙5开发宝藏案例分享---一多断点开发实践

    ?【鸿蒙开发实战进阶】六大核心案例深度拆解,带你玩转多端适配!? 案例4:动态网格布局(电商商品列表)应用场景:手机/平板商品展示差异 痛点分析:手机单列→平板多列,需智能计算展示数量
    发表于 05-30 11:08

    如何在KaihongOS操作系统中写一个动态的页面

    SecondPage.ets是空白的,需要开发者自行编写代码。 添加文本及按钮 参照Index.ets页面,在SecondPage.ets页面中添加Text组件、Button组件等,
    发表于 04-25 06:42

    DevEco Studio 写一个简单的页面

    MyApplication的项目,我们将在此项目上进行后续的开发。 首先为了项目的可识别性,将项目名称修改为simple_demo。 将项目的目录展开,进入src/main/ets/pages/目录下,在
    发表于 04-24 07:36

    HarmonyOS NEXT开发实战:DevEco AI辅助编程工具(CodeGenie)的使用

    引言 DevEco AI辅助编程工具(CodeGenie)为开发者提供高效的应用/元服务AI辅助编程工具,支持HarmonyOS NEXT领域的智能知识问答、ArkTS代码补全/生成和万能卡片生成
    发表于 03-10 15:41

    罗德与施瓦茨和ETS-Lindgren发布新一代无线技术OTA测试解决方案

    罗德与施瓦茨(以下简称“R&S”)和 ETS-Lindgren 持续合作,为新一代无线技术提供全面的OTA 测试解决方案。ETS-Lindgren 将R&S CMX500一体化信令
    的头像 发表于 12-18 11:24 889次阅读