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

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

3天内不再提示

HarmonyOS开发案例:【使用List组件实现商品列表】

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-05-10 16:41 次阅读

介绍

OpenHarmony ArkTS提供了丰富的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。在本篇Codelab中,我们使用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开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以3.2 Release版本为例:
  2. 搭建烧录环境。
    1. [完成DevEco Device Tool的安装]
    2. [完成RK3568开发板的烧录]
  3. 搭建开发环境。
    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”),选择JS或者eTS语言开发。
    3. 工程创建完成后,选择使用[真机进行调测]。
    4. 鸿蒙开发指导文档:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

代码结构解读

本篇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                  // 中文字符存放位置
           
`HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

搜狗高速浏览器截图20240326151450.png

页面布局

页面使用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)
})

审核编辑 黄宇

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

    关注

    1

    文章

    504

    浏览量

    17799
  • 鸿蒙
    +关注

    关注

    57

    文章

    2306

    浏览量

    42730
  • HarmonyOS
    +关注

    关注

    79

    文章

    1967

    浏览量

    29997
  • OpenHarmony
    +关注

    关注

    25

    文章

    3657

    浏览量

    16129
收藏 人收藏

    评论

    相关推荐

    HarmonyOS开发案例:【 slider组件的使用】

    主要介绍slider滑动条组件的使用。如图所示拖动对应滑动条调节风车的旋转速度以及缩放比例。
    的头像 发表于 04-25 22:02 876次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【 slider<b class='flag-5'>组件</b>的使用】

    HarmonyOS开发案例:【使用List组件实现设置项】

    使用List组件、Toggle组件以及Router接口,实现一个简单的设置页,点击将跳转到对应的详细设置页面。
    的头像 发表于 05-10 17:01 865次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【使用<b class='flag-5'>List</b><b class='flag-5'>组件</b><b class='flag-5'>实现</b>设置项】

    HarmonyOS开发案例:【Web组件实现抽奖】

    基于ArkTS的声明式开发范式的样例,主要介绍了Web组件如何加载本地和云端H5小程序。
    的头像 发表于 05-09 18:31 1317次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【Web<b class='flag-5'>组件</b><b class='flag-5'>实现</b>抽奖】

    HarmonyOS开发案例:【基础组件Slider的使用】

    学习如何使用声明式UI编程框架的基础组件。本篇Codelab将会使用Image组件、Slider组件、Text组件共同实现一个可调节的风车动
    的头像 发表于 05-10 16:01 640次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【基础<b class='flag-5'>组件</b>Slider的使用】

    HarmonyOS开发案例:【常用组件与布局】

    HarmonyOS ArkUI提供了丰富多样的UI组件,您可以使用这些组件轻松地编写出更加丰富、漂亮的界面。
    的头像 发表于 05-09 18:20 1163次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【常用<b class='flag-5'>组件</b>与布局】

    HarmonyOS开发案例:【排行榜页面】

    本课程使用声明式语法和组件化基础知识,搭建一个可刷新的排行榜页面。在排行榜页面中,使用循环渲染控制语法来实现列表数据渲染,使用@Builder创建排行列表布局内容,使用装饰器@Stat
    的头像 发表于 04-30 16:16 1889次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【排行榜页面】

    HarmonyOS开发案例:【待办列表

    使用ArkTS声明式语法和基础组件实现简易待办列表。效果为点击某一事项,替换标签图片、虚化文字。
    的头像 发表于 05-06 15:22 998次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【待办<b class='flag-5'>列表</b>】

    鸿蒙开发实战-(ArkUI)List组件和Grid组件的使用

    一系列相同宽度的列表项,连续、多行呈现同类数据,例如图片和文本。常见的列表有线性列表List列表)和网格布局(Grid
    发表于 01-18 20:18

    【基于HarmonyOS开发购物应用】AnBetter Codelab第二期记录帖

    量。应用包含两级页面,分别是主页(商品浏览页签、购物车页签、我的页签)和商品详情页面,两个页面都展示了丰富的HarmonyOS UI组件,包括:自定义弹窗容器(dialog),
    发表于 04-17 00:55

    使用JS实现一款简单的HarmonyOS购物应用

    1. 介绍本篇Codelab将会使用UI组件开发出一个HarmonyOS购物应用。HarmonyOS开发者提供了多种
    发表于 09-23 10:40

    HarmonyOS应用开发资料(Svg组件

    1、HarmonyOS应用开发-Svg组件circle  该组件从API version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。2、
    发表于 03-17 14:49

    HarmonyOS/OpenHarmony应用开发-声明式开发范式组件汇总

    组件是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。声明式
    发表于 01-19 11:14

    如何用JS UI框架的List组件画一个表格?

    UI框架的List组件画一个表格”。 作者通过List组件快速、高效地构建了一个自定义表格。接下来,让我们一起见证作者是如何遇到问题,解决问题,最终
    的头像 发表于 07-01 10:42 2187次阅读

    华为开发者分论坛HarmonyOS学生公开课-OpenHarmony Codelabs开发案

    2021华为开发者分论坛HarmonyOS学生公开课-OpenHarmony Codelabs开发案
    的头像 发表于 10-24 11:25 1882次阅读
    华为<b class='flag-5'>开发</b>者分论坛<b class='flag-5'>HarmonyOS</b>学生公开课-OpenHarmony Codelabs<b class='flag-5'>开发案</b>例

    HarmonyOS开发案例:【 switch、chart组件的使用】

    基于switch组件和chart组件实现线形图、占比图、柱状图,并通过switch切换chart组件数据的动静态显示。
    的头像 发表于 04-25 20:58 562次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【 switch、chart<b class='flag-5'>组件</b>的使用】