OpenHarmony ArkTS提供了丰富的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。
在本篇文章中,我们使用Scroll、List以及LazyForEach实现一个商品列表的页面,并且拥有下拉刷新,懒加载和到底提示的效果。效果图如下:
相关概念
- Scroll:可滚动的容器组件,当子组件的布局尺寸超过父组件的视口时,内容可以滚动。
- List:列表包含一系列相同宽度的列表项。适合连续、多行呈现同类数据,例如图片和文本。
- Tabs:一种可以通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。
- LazyForEach :开发框架提供数据懒加载(LazyForEach组件)从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
环境搭建
软件要求
- DevEco Studio版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 开发板类型:润和RK3568开发板。
- OpenHarmony系统:3.2 Release。
环境搭建
完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:
-
获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:
-
搭建烧录环境。
-
搭建开发环境。
代码结构解读
本篇Codelab只对核心代码进行讲解,完整代码可以直接从gitee获取。
├──entry/src/main/ets // 代码区
│ ├──common
│ │ └──CommonConstants.ets // 常量集合文件
│ ├──entryability
│ │ └──EntryAbility.ts // 应用入口,承载应用的生命周期
│ ├──pages
│ │ └──ListIndex.ets // 页面入口
│ ├──view
│ │ ├──GoodsListComponent.ets // 商品列表组件
│ │ ├──PutDownRefreshLayout.ets // 下拉刷新组件
│ │ └──TabBarsComponent.ets // Tabs组件
│ └──viewmodel
│ ├──InitialData.ets // 初始化数据
│ └──ListDataSource.ets // List使用的相关数据加载
└──entry/src/main/resources
├──base
│ ├──element // 字符串以及颜色的资源文件
│ ├──media // 图片等资源文件
│ └──profile // 页面配置文件存放位置
├──en_US
│ └──element
│ └──string.json // 英文字符存放位置
└──zh_CN
└──element
└──string.json // 中文字符存放位置
页面布局
页面使用Navigation与Tabs做页面布局,使用Navigation的title属性实现页面的标题,Tabs做商品内容的分类。示例代码如下:
// ListIndex.ets
Row() {
Navigation() {
Column() {
TabBars()
}
.width(LAYOUT_WIDTH_OR_HEIGHT)
.justifyContent(FlexAlign.Center)
}
.size({ width: LAYOUT_WIDTH_OR_HEIGHT, height: LAYOUT_WIDTH_OR_HEIGHT })
.title(STORE)
.titleMode(NavigationTitleMode.Mini)
}
.height(LAYOUT_WIDTH_OR_HEIGHT)
.backgroundColor($r('app.color.primaryBgColor'))
页面分为“精选”、“手机”、“服饰”、“穿搭”、“家居”五个模块,由于本篇CodeLab的主要内容在“精选”部分,故将“精选”部分单独编写代码,其余模块使用ForEach遍历生成。示例代码如下:
// TabBarsComponent.ets
Tabs() {
// 精选模块
TabContent() {
Scroll() {
Column() {
if (this.refreshStatus) {
PutDownRefresh({ refreshText: $refreshText })
}
GoodsList()
Text($r('app.string.to_bottom'))
.fontSize(NORMAL_FONT_SIZE)
.fontColor($r('app.color.gray'))
}
.width(LAYOUT_WIDTH_OR_HEIGHT)
}
...
}
.tabBar(this.firstTabBar)
// 其他模块
ForEach(initTabBarData, (item: Resource, index?: number) => {
TabContent() {
Column() {
Text(item).fontSize(MAX_FONT_SIZE)
}
.justifyContent(FlexAlign.Center)
.width(LAYOUT_WIDTH_OR_HEIGHT)
.height(LAYOUT_WIDTH_OR_HEIGHT)
}
.tabBar(this.otherTabBar(item, index !== undefined ? index : 0))
})
}
...
商品列表的懒加载
使用Scroll嵌套List做长列表,实现Scroll与List的联动。具体实现代码如下:
// TabBarsComponent.ets
Scroll() {
Column() {
// 下拉刷新的组件
if (this.refreshStatus) {
PutDownRefresh({ refreshText:$refreshText })
}
// List的自定义组件
GoodsList()
Text($r('app.string.to_bottom')).fontSize(NORMAL_FONT_SIZE).fontColor($r('app.color.gray'))
}
.width(LAYOUT_WIDTH_OR_HEIGHT)
}
...
商品列表往往数据量很多,如果使用ForEach一次性遍历生成的话,性能不好,所以这里使用LazyForEach进行数据的懒加载。当向下滑动时,需要加载新的数据的时候,再将新的数据加载出来,生成新的列表。
通过onTouch事件来触发懒加载行为,当商品列表向下滑动,加载新的数据。示例代码如下:
// GoodsListComponent.ets
List({ space:commonConst.LIST_ITEM_SPACE }) {
LazyForEach(this.goodsListData, (item: GoodsListItemType) => {
ListItem() {
Row() {
Column() {
Image(item?.goodsImg)
...
}
... // 布局样式
Column() {
... // 布局代码
}
... // 布局样式
}
}
// 通过Touch事件来触发懒加载
.onTouch((event?:TouchEvent) => {
if (event === undefined) {
return;
}
switch (event.type) {
case TouchType.Down:
this.startTouchOffsetY = event.touches[0].y;
break;
case TouchType.Up:
this.startTouchOffsetY = event.touches[0].y;
break;
case TouchType.Move:
if (this.startTouchOffsetY - this.endTouchOffsetY > 0) {
this.goodsListData.pushData();
}
break;
}
})
})
}
...
下拉刷新与到底提示
下拉刷新同样使用TouchEvent做下拉的判断,当下拉的偏移量超出将要刷新的偏移量时,就展示下拉刷新的布局,同时使用条件渲染判断是否显示下拉刷新布局,实现效果如下图:
具体代码如下:
// TabBarsComponent.ets
putDownRefresh(event?:TouchEvent): void {
if (event === undefined) {
return;
}
switch (event.type) {
case TouchType.Down:
// 记录手指按下的y坐标
this.currentOffsetY = event.touches[0].y;
break;
case TouchType.Move:
// 根据下拉的偏移量来判断是否刷新
this.refreshStatus = event.touches[0].y - this.currentOffsetY > MAX_OFFSET_Y;
break;
case TouchType.Cancel:
break;
case TouchType.Up:
// 模拟刷新效果,并未真实请求数据
this.timer = setTimeout(() => {
this.refreshStatus = false;
}, REFRESH_TIME)
break;
}
}
...
// 下拉刷新的组件根据条件决定是否显示
if (this.refreshStatus) {
PutDownRefresh({ refreshText:$refreshText })
}
列表到底提示“已经到底了”并回弹的效果使用了Scroll的edgeEffect来控制回弹,实现效果如下图:
具体代码如下:
// TabBarsComponent.ets
Scroll() {
Column() {
...
GoodsList()
Text($r('app.string.to_bottom')).fontSize(NORMAL_FONT_SIZE).fontColor($r('app.color.gray'))
}
.width(LAYOUT_WIDTH_OR_HEIGHT)
}
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring)
.width(LAYOUT_WIDTH_OR_HEIGHT)
.height(LAYOUT_WIDTH_OR_HEIGHT)
.onTouch((event?: TouchEvent) => {
this.putDownRefresh(event)
})
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(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学习资料
总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。