乐趣区

关于harmonyos:基于eTS高效开发HarmonyOS课程类应用

随着 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 容器别离作为利用界面的导航栏布局和课程内容布局,上面咱们将为你一一道来。

                                   图 1 整体布局

1. 导航栏布局
利用界面的导航栏应用可滚动的容器组件 Scroll 来实现,Scroll 内嵌 Text 组件用于显示“课程分类”名称,如图 2 所示:

                                  图 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 所示,课程内容布局蕴含头部和课程信息两局部(头部和右边的导航栏对应),上面咱们将别离介绍头部及课程信息的布局的实现。

                                 图 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 = 0
model.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)

通过上文的介绍,咱们曾经实现了利用界面的布局以及界面数据的出现,此时界面就像没有灵魂的躯壳。上面咱们将为大家介绍利用中联动成果的实现。

四、实现界面联动

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

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 形容、循环渲染、状态数据管理等机制,赶快趁热打铁,开发更多乏味的利用吧!

退出移动版