OpenHarmony实战开发-List组件的使用之设置项

介绍

在本篇CodeLab中,我们将使用List组件、Toggle组件以及Router接口,实现一个简单的设置页,点击将跳转到对应的详细设置页面。效果图如下:

相关概念

  • @CustomDialog:@CustomDialog装饰器用于装饰自定义弹窗。
  • List:List是常用的滚动类容器组件之一,它按照水平或者竖直方向线性排列子组件, List的子组件必须是ListItem,它的宽度默认充满List的宽度。
  • TimePicker:TimePicker是选择时间的滑动选择器组件,默认以 00:00 至 23:59 的时间区创建滑动选择器。
  • Toggle:组件提供勾选框样式、状态按钮样式及开关样式。
  • Router:通过不同的url访问不同的页面,包括跳转到应用内的指定页面、用应用内的某个页面替换当前页面、返回上一页面或指定的页面等。

环境搭建

软件要求

  • 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. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets                        // 代码区
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstant.ets               // 常量集合文件
│  │  └──utils
│  │     ├──BroadCast.ets                    // 事件发布订阅管理器
│  │     └──Log.ets                          // 日志打印
│  ├──entryability
│  │  └──EntryAbility.ts                     // 应用入口,承载应用的生命周期
│  ├──model
│  │  ├──EventSourceManager.ets              // 事件资源管理器
│  │  ├──TaskInfo.ets                        // 任务信息存放
│  │  └──TaskInitList.ets                    // 初始化数据
│  ├──pages
│  │  ├──ListIndexPage.ets                   // 页面入口
│  │  └──TaskEditPage.ets                    // 编辑任务页
│  ├──view
│  │  ├──CustomDialogView.ets                // 自定义弹窗统一入口
│  │  ├──TaskDetail.ets                      // 任务编辑详情组件
│  │  ├──TaskEditListItem.ets                // 任务编辑详情Item组件
│  │  ├──TaskList.ets                        // 任务列表组件
│  │  └──TaskSettingDialog.ets               // 弹窗组件
│  └──viewmodel
│     ├──FrequencySetting.ets                // 频率范围设置
│     └──TaskTargetSetting.ets               // 任务目标设置
└──entry/src/main/resources
   ├──base
   │  ├──element                             // 字符串以及颜色的资源文件
   │  ├──media                               // 图片等资源文件
   │  └──profile                             // 页面配置文件存放位置
   ├──en_US
   │  └──element
   │     └──string.json                      // 英文字符存放位置
   ├──rawfile                                // 大体积媒体资源存放位置
   └──zh_CN
       └──element
          └──string.json                     // 中文字符存放位置

任务列表页

任务列表页由上部分的标题、返回按钮以及正中间的任务列表组成。实现效果如图:

使用Navigation以及List组件构成元素,使用ForEach遍历生成具体列表。这里是Navigation构成页面导航:

// ListIndexPage.ets
Navigation() {
  Column() {

    // 页面中间的列表
    TaskList() 
  }
  .width(THOUSANDTH_1000)
  .justifyContent(FlexAlign.Center)
}
.size({ width:THOUSANDTH_1000, height:THOUSANDTH_1000 })
.title(ADD_TASK_TITLE)

列表右侧有一个判断是否开启的文字标识,点击某个列表需要跳转到对应的任务编辑页里。具体的列表实现如下:

// TaskList.ets
List({ space:commonConst.LIST_ITEM_SPACE }) {
  ForEach(this.taskList, (item: TaskListItem) => {
    ListItem() {
      Row() {
        Row() {
          Image(item?.icon)
          ...
          Text(item?.taskName)
          ...
        }
        .width(commonConst.THOUSANDTH_500)

        // 状态显示
        if (item?.isOpen) {
          Text($r('app.string.already_open'))
            ...
        }
        Image($r('app.media.right_grey'))
        ...
      }
        ...
    }
      ...
    // 路由跳转到任务编辑页
    .onClick(() => {
      router.pushUrl({
        url: 'pages/TaskEditPage',
        params: {
          params: formatParams(item),
        }
      })
    })
    ...
  })
}

任务编辑页

任务编辑页由上方的“编辑任务”标题以及返回按钮,主体内容的List配置项和下方的完成按钮组成,实现效果如图:

由于每一个配置项功能不相同,且逻辑复杂,故将其拆分为五个独立的组件。

任务编辑页面,由Navigation和一个自定义组件TaskDetail构成:

// TaskEditPage.ets
Navigation() {
  Column() {
    TaskDetail()
  }
  .width(THOUSANDTH_1000)
  .height(THOUSANDTH_1000)
}
.size({ width:THOUSANDTH_1000, height:THOUSANDTH_1000 })
.title(EDIT_TASK_TITLE)
.titleMode(NavigationTitleMode.Mini)

自定义组件由List以及其子组件ListItem构成:

// TaskDetail.ets
List({ space:commonConst.LIST_ITEM_SPACE }) {
  ListItem() {
    TaskChooseItem()
  }
  ...
  ListItem() {
    TargetSetItem()
  }
  ...
  ListItem() {
    OpenRemindItem()
  }
  ...
  ListItem() {
    RemindTimeItem()
  }
  ...
  ListItem() {
    FrequencyItem()
  }
  ...
}
.width(commonConst.THOUSANDTH_940)

列表的每一项做了禁用判断,需要任务打开才可以点击编辑:

// TaskDetail.ets
.enabled(this.settingParams?.isOpen)

一些特殊情况的禁用,如每日微笑、每日刷牙的目标设置不可编辑:

// TaskDetail.ets
.enabled(
  this.settingParams?.isOpen
  && (this.settingParams?.taskID !== taskType.smile)
  && (this.settingParams?.taskID !== taskType.brushTeeth)
)

提醒时间在开启提醒打开之后才可以编辑:

// TaskDetail.ets
.enabled(this.settingParams?.isOpen && this.settingParams?.isAlarm)

设置完成之后,点击完成按钮,此处为了模拟效果,并不与数据库产生交互,因此直接弹出提示“设置完成!!!”。

// TaskDetail.ets
finishTaskEdit() {
  prompt.showToast({
    message: commonConst.SETTING_FINISHED_MESSAGE
  })
}

任务编辑弹窗

弹窗由封装的自定义组件CustomDialogView注册事件,并在点击对应的编辑项时触发,从而打开弹窗:

CustomDialogView引入实例并注册事件:

// CustomDialogView.ets
targetSettingDialog = new CustomDialogController({
  builder: TargetSettingDialog(),
  autoCancel: true,
  alignment: DialogAlignment.Bottom,
  offset: { dx:ZERO, dy:MINUS_20 }
})
...

// 注册事件
this.broadCast.on(
  BroadCastType.SHOW_FREQUENCY_DIALOG,
  () => {
    this.FrequencyDialogController.open();
  })

点击对应的编辑项触发:

// TaskDetail.ets
.onClick(() => {
  if (this.broadCast !== undefined) {
    this.broadCast.emit(
      BroadCastType.SHOW_TARGET_SETTING_DIALOG);
  }
})

自定义弹窗的实现:

因为任务目标设置有三种类型:

  • 早睡早起的时间
  • 喝水的量度
  • 吃苹果的个数

如下图所示:

故根据任务的ID进行区分,将同一弹窗复用:

// TaskSettingDialog.ets
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams?.taskID) > commonConst.HAS_NO_INDEX) {
  TimePicker({
    selected:commonConst.DEFAULT_SELECTED_TIME
  })
  ...
} else {
  TextPicker({ range:this.settingParams?.taskID === taskType.drinkWater ? this.drinkRange : this.appleRange,
    value: this.settingParams.targetValue})
  ...
}

弹窗确认的时候将修改好的值赋予该项设置,如不符合规则,将弹出提示:

// TaskSettingDialog.ets
// 校验规则
compareTime(startTime: string, endTime: string) {
  if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) ||
    returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {

    // 弹出提示
    prompt.showToast({
      message:commonConst.CHOOSE_TIME_OUT_RANGE
    })
    return false;
  }
  return true;
}

// 设置修改项
if (this.settingParams?.taskID === taskType.sleepEarly) {
  if (!this.compareTime(commonConst.SLEEP_EARLY_TIME, commonConst.SLEEP_LATE_TIME)) {
    return;
  }
  this.settingParams.targetValue = this.currentTime;
  return;
}
this.settingParams.targetValue = this.currentValue;

其余弹窗实现基本类似,这里不再赘述。

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 使用List组件实现列表布局。
  2. 使用@CustomDialog实现自定义弹窗。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?鸿蒙基础入门学习指南》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册


http://www.niftyadmin.cn/n/5456795.html

相关文章

Rabbitmq消息重复消费

1、消息何时会重复消费 自动提交模式时 消费者进行处理后&#xff0c;会给队列发送一个ack(参考上一篇的消息丢失)&#xff0c;但是这个ack在中途丢失了&#xff0c;导致队列以为消费者没有成功消费。所以就不会删除这个消息&#xff0c;会进行重新消费。 手动提交模式 用户手动…

【SpringCloud微服务实战10】DevOps自动化部署微服务项目(Jenkins+Docker+K8s)

一、什么是 DevOps DevOps 是一种重视软件开发人员(Developer)和运维人员(Operations)之间沟通与协作的文化、运动或实践,目标在于快速交付高质量的软件产品和服务。DevOps 强调自动化流程、持续集成与交付(CI/CD)、以及通过工具链、敏捷方法论和跨职能团队协作来增强软…

nginx部署视频服务(视频下载链接也ok),vue前端如何播放视频

浏览器点击链接就出现播放&#xff0c;我想利用前端vue,让其播放视频&#xff0c;怎么做&#xff1f; //播放视频viewVideo(row, type) {console.log("row", row);console.log("totalBatch", row.totalBatch, "idNumber", row.idNumber, "b…

基于策略模式实现不同的搜索分发

要根据搜索类型使用策略模式实现不同的搜索逻辑&#xff0c;首先需要定义一个策略接口和一系列实现了该接口的策略类&#xff0c;每个类对应一种搜索类型。然后&#xff0c;创建一个上下文类&#xff0c;它根据传入的搜索类型动态选择使用哪个搜索策略&#xff0c;并提供一个统…

案例分享:F5助力车企打造智能高效自动化应用

纵观当下的汽车市场&#xff0c;智能汽车百花齐放。自动驾驶、车载娱乐、实时3D地图等实现人机互动的出行场景&#xff0c;解锁着全新的出行方式。然而得到独特而先进的智能用车体验&#xff0c;离不开持续而深入的汽车应用变革。那么怎样打造智能高效的自动化应用呢&#xff1…

springcloud微服务项目,通过gateway+nacos实现灰度发布(系统不停机升级)

一、背景 灰度发布的目的是保证系统的高可用&#xff0c;不停机&#xff0c;提升用户体验。在微服务系统中&#xff0c;原有系统不下线&#xff0c;新版系统与原有系统同时在线&#xff0c;通过访问权重在线实时配置&#xff0c;可以让少量用户先应用新版本功能&#xff0c;如…

自动化更新包文件--shell脚本

自动化更新包文件--shell脚本 背景手动更包自动化更包 背景 作为一名实施工程师&#xff0c;当然也协助做些测试的工作&#xff0c;当产品功能开发后&#xff0c;研发会将本次迭代涉及的前后端包文件提供过来。有时会因为一些原因研发没法现场开发&#xff0c;那就需要我们配合…

京东云0基础搭建帕鲁服务器_4核16G和8核32G幻兽帕鲁专用服务器

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云atengyun.…