HarmonyOS开发案例:【生活健康app之实现打卡功能】(2)

实现打卡功能

首页会展示当前用户已经开启的任务列表,每条任务会显示对应的任务名称以及任务目标、当前任务完成情况。用户只可对当天任务进行打卡操作,用户可以根据需要对任务列表中相应的任务进行点击打卡。如果任务列表中的每个任务都在当天完成则为连续打卡一天,连续打卡多天会获得成就徽章。打卡效果如下图所示:

开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

任务列表

使用List组件展示用户当前已经开启的任务,每条任务对应一个TaskCard组件,clickAction包装了点击和长按事件,用户点击任务卡时会触发弹起打卡弹窗,从而进行打卡操作;长按任务卡时会跳转至任务编辑界面,对相应的任务进行编辑处理。代码如下:

// HomeComponent.ets
// 任务列表
ForEach(this.homeStore.getTaskListOfDay(), (item: TaskInfo) => {TaskCard({taskInfoStr: JSON.stringify(item),clickAction: (isClick: boolean) => this.taskItemAction(item, isClick)}).margin({ bottom: Const.DEFAULT_12 }).height($r('app.float.default_64'))
}, (item: TaskInfo) => JSON.stringify(item))
...
CustomDialogView() // 自定义弹窗中间件
自定义弹窗中间件CustomDialogView

在组件CustomDialogView的aboutToAppear生命周期中注册SHOW_TASK_DETAIL_DIALOG的事件回调方法 ,当通过emit触发此事件时即触发回调方法执行。代码如下:

// CustomDialogView.ets
export class CustomDialogCallback {confirmCallback: Function = () => {};cancelCallback: Function = () => {};
}@Component
export struct CustomDialogView {@State isShow: boolean = false;@Provide achievementLevel: number = 0;@Consume broadCast: BroadCast;@Provide currentTask: TaskInfo = TaskItem;@Provide dialogCallBack: CustomDialogCallback = new CustomDialogCallback();// 成就对话框achievementDialog: CustomDialogController = new CustomDialogController({builder: AchievementDialog(),autoCancel: true,customStyle: true});// 任务时钟对话框taskDialog: CustomDialogController = new CustomDialogController({builder: TaskDetailDialog(),autoCancel: true,customStyle: true});aboutToAppear() {Logger.debug('CustomDialogView', 'aboutToAppear');// 成就对话框this.broadCast.on(BroadCastType.SHOW_ACHIEVEMENT_DIALOG, (achievementLevel: number) => {Logger.debug('CustomDialogView', 'SHOW_ACHIEVEMENT_DIALOG');this.achievementLevel = achievementLevel;this.achievementDialog.open();});// 任务时钟对话框this.broadCast.on(BroadCastType.SHOW_TASK_DETAIL_DIALOG,(currentTask: TaskInfo, dialogCallBack: CustomDialogCallback) => {Logger.debug('CustomDialogView', 'SHOW_TASK_DETAIL_DIALOG');this.currentTask = currentTask || TaskItem;this.dialogCallBack = dialogCallBack;this.taskDialog.open();});}aboutToDisappear() {Logger.debug('CustomDialogView', 'aboutToDisappear');}build() {}
}
点击任务卡片

点击任务卡片会emit触发 “SHOW_TASK_DETAIL_DIALOG” 事件,同时把当前任务,以及确认打卡回调方法传递下去。代码如下:

// HomeComponent.ets
// 任务卡片事件
taskItemAction(item: TaskInfo, isClick: boolean): void {...if (isClick) {// 点击任务打卡let callback: CustomDialogCallback = { confirmCallback: (taskTemp: TaskInfo) => {this.onConfirm(taskTemp)}, cancelCallback: () => {} };// 触发弹出打卡弹窗事件  并透传当前任务参数(item) 以及确认打卡回调this.broadCast.emit(BroadCastType.SHOW_TASK_DETAIL_DIALOG, [item, callback]);} else {// 长按编辑任务...}
}
// 确认打卡
onConfirm(task) {this.homeStore.taskClock(task).then((res: AchievementInfo) => {// 打卡成功后 根据连续打卡情况判断是否 弹出成就勋章  以及成就勋章级别if (res.showAchievement) {// 触发弹出成就勋章SHOW_ACHIEVEMENT_DIALOG 事件, 并透传勋章类型级别let achievementLevel = res.achievementLevel;if (achievementLevel) {this.broadCast.emit(BroadCastType.SHOW_ACHIEVEMENT_DIALOG, achievementLevel);} else {this.broadCast.emit(BroadCastType.SHOW_ACHIEVEMENT_DIALOG);}}})
}

打卡弹窗组件TaskDetailDialog

打卡弹窗组件根据当前任务的ID获取任务名称以及弹窗背景图片资源。

打卡弹窗组件由两个小组件构成,代码如下:

// TaskDetailDialog.ets
Column() {// 展示任务的基本信息TaskBaseInfo({taskName: TaskMapById[this.currentTask?.taskID - 1].taskName  // 根据当前任务ID获取任务名称});// 打卡功能组件 (任务打卡、关闭弹窗)TaskClock({confirm: () => {this.dialogCallBack.confirmCallback(this.currentTask);this.controller.close();},cancel: () => {this.controller.close();},showButton: this.showButton})
}
...

TaskBaseInfo组件代码如下:

// TaskDetailDialog.ets
@Component
struct TaskBaseInfo {taskName: string | Resource = '';build() {Column({ space: Const.DEFAULT_8 }) {Text(this.taskName).fontSize($r('app.float.default_22')).fontWeight(FontWeight.Bold).fontFamily($r('app.string.HarmonyHeiTi_Bold')).taskTextStyle().margin({left: $r('app.float.default_12')})}.position({ y: $r('app.float.default_267') })}
}

TaskClock组件代码如下:

// TaskDetailDialog.ets
@Component
struct TaskClock {confirm: Function = () => {};cancel: Function = () => {};showButton: boolean = false;build() {Column({ space: Const.DEFAULT_12 }) {Button() {Text($r('app.string.clock_in')).height($r('app.float.default_42')).fontSize($r('app.float.default_20')).fontWeight(FontWeight.Normal).textStyle()}.width($r('app.float.default_220')).borderRadius($r('app.float.default_24')).backgroundColor('rgba(255,255,255,0.40)').onClick(() => {GlobalContext.getContext().setObject('taskListChange', true);this.confirm();}).visibility(!this.showButton ? Visibility.None : Visibility.Visible)Text($r('app.string.got_it')).fontSize($r('app.float.default_14')).fontWeight(FontWeight.Regular).textStyle().onClick(() => {this.cancel();})}}
}

打卡接口调用

// HomeViewModel.ets
public async taskClock(taskInfo: TaskInfo) {let taskItem = await this.updateTask(taskInfo);let dateStr = this.selectedDayInfo?.dateStr;// 更新任务失败if (!taskItem) {return {achievementLevel: 0,showAchievement: false} as AchievementInfo;}// 更新当前时间的任务列表this.selectedDayInfo.taskList = this.selectedDayInfo.taskList.map((item) => {return item.taskID === taskItem?.taskID ? taskItem : item;});let achievementLevel: number = 0;if(taskItem.isDone) {// 更新每日任务完成情况数据let dayInfo = await this.updateDayInfo();... // 当日任务完成数量等于总任务数量时 累计连续打卡一天// 更新成就勋章数据 判断是否弹出获得勋章弹出及勋章类型if (dayInfo && dayInfo?.finTaskNum === dayInfo?.targetTaskNum) {achievementLevel = await this.updateAchievement(this.selectedDayInfo.dayInfo);}}...return {achievementLevel: achievementLevel,showAchievement: ACHIEVEMENT_LEVEL_LIST.includes(achievementLevel)} as AchievementInfo;
}`HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

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

// HomeViewModel.ets
// 更新当天任务列表
updateTask(task: TaskInfo): Promise<TaskInfo> {return new Promise((resolve, reject) => {let taskID = task.taskID;let targetValue = task.targetValue;let finValue = task.finValue;let updateTask = new TaskInfo(task.id, task.date, taskID, targetValue, task.isAlarm, task.startTime,task.endTime, task.frequency, task.isDone, finValue, task.isOpen);let step = TaskMapById[taskID - 1].step; // 任务步长let hasExceed = updateTask.isDone;if (step === 0) { // 任务步长为0 打卡一次即完成该任务updateTask.isDone = true; // 打卡一次即完成该任务updateTask.finValue = targetValue;} else {let value = Number(finValue) + step; // 任务步长非0 打卡一次 步长与上次打卡进度累加updateTask.isDone = updateTask.isDone || value >= Number(targetValue); // 判断任务是否完成updateTask.finValue = updateTask.isDone ? targetValue : `${value}`;}TaskInfoTableApi.updateDataByDate(updateTask, (res: number) => { // 更新数据库if (!res || hasExceed) {Logger.error('taskClock-updateTask', JSON.stringify(res));reject(res);}resolve(updateTask);})})
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3029895.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

安装vmware station记录

想学一下linux,花了3个多小时&#xff0c;才配置好了&#xff0c;记录一下 安装vm12,已配置linux系统 报错&#xff0c;VMware Workstation 与 Device/Credential Guard 不兼容解决方案&#xff0c;网上说有不成功的&#xff0c;电脑蓝屏&#xff0c;选择装vm16试试 vm16 在…

【JVM】JVM规范作用及其核心

目录 认识JVM规范的作用 JVM规范定义的主要内容 认识JVM规范的作用 Java 虚拟机规范为不同的硬件平台提供了一种编译Java技术代码的规范。 Java虚拟机认得不是源文件&#xff0c;认得是编译过后的class文件&#xff0c;它是对这个class文件做要求、起作用的&#xff0c;而并…

算法设计与分析 动态规划/回溯

1.最大子段和 int a[N]; int maxn(int n) {int tempa[0];int ans0;ansmax(temp,ans);for(int i1;i<n;i){if(temp>0){tempa[i];}else tempa[i];ansmax(temp,ans);}return ans; } int main() {int n,ans0;cin>>n;for(int i0;i<n;i) cin>>a[i];ansmaxn(n);co…

LeetCode例题讲解:876.链表的中间结点

给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点&#xff0c;值为 3 。…

kubernetes删除命名空间下所有资源

kubernetes强制删除命名空间下所有资源 在 Kubernetes 中&#xff0c;当一个命名空间处于 Terminating 状态但不会完成删除过程时&#xff0c;通常是因为内部资源没有被正确清理。要强制删除这个命名空间及其所有资源&#xff0c;你可以采取以下步骤&#xff1a; 1. 确认命名空…

渲染农场评测:6大热门云渲染平台全面比较

在3D行业中&#xff0c;选择一个合适的云渲染平台可能会令许多专业人士感到难以抉择。为此&#xff0c;我们精心准备了6家流行云渲染平台的详尽评测&#xff0c;旨在为您的决策过程提供实用的参考和支持。 目前&#xff0c;市面上主要的3D网络渲染平台包括六大服务商&#xff0…

张驰咨询六西格玛黑带培训,上海开班,质量精英的摇篮!

一、课程背景与意义 在当今竞争激烈的市场环境中&#xff0c;企业要想立于不败之地&#xff0c;就必须不断提升自身的核心竞争力。而六西格玛作为一种先进的质量管理工具和方法&#xff0c;已经被越来越多的企业所采纳。通过六西格玛黑带培训&#xff0c;学员们可以系统地掌握…

【c++算法篇】双指针(下)

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;算法笔记仓 朋友们大家好啊&#xff0c;本篇文章我们来到算法的双指针的第二部分 目录 1.有效三角形的个数2.查找总价格为目标值的两个商品3.三数之和4.四数之和5.双指针常见场景总结 1.有效三角形…

CAPL如何实现TLS握手认证

CAPL有专门的章节介绍如何实现TLS握手认证的函数: CAPL调用哪些函数实现TLS握手认证,需要了解TLS在整个通信过程的哪个阶段。 首先TCP需要建立连接,这是TLS握手的前提。当TLS握手认证完成后,可以传输数据。 所以TLS握手开始前需要确保TCP建立连接,TCP传输数据前需要确保…

基于SSM的文化遗产的保护与旅游开发系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的文化遗产的保护与旅游开发系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

适合年轻人的恋爱交友脱单软件有哪些?中国十大社交软件排行榜分享

交友始祖&#xff1a;Tinder 一直很受欢迎&#xff0c;可以向上扫给 super like (每日有一次免费机会)。如果双方互相 like&#xff0c;代表配对成功&#xff0c;就可以开始聊天。另外&#xff0c;每日有 10 个 top picks 供选择&#xff0c;你可以免费选一位 主力编外&#xf…

K8s源码分析(二)-K8s调度队列介绍

本文首发在个人博客上&#xff0c;欢迎来踩&#xff01; 本次分析参考的K8s版本是 文章目录 调度队列简介调度队列源代码分析队列初始化QueuedPodInfo元素介绍ActiveQ源代码介绍UnschedulableQ源代码介绍**BackoffQ**源代码介绍队列弹出待调度的Pod队列增加新的待调度的Podpod调…

数据分析:基于sparcc的co-occurrence网络

介绍 Sparcc是基于16s或metagenomics数据等计算组成数据之间关联关系的算法。通常使用count matrix数据。 安装Sparcc软件 git clone gitgithub.com:JCSzamosi/SparCC3.git export PATH/path/SparCC3:$PATHwhich SparCC.py导入数据 注&#xff1a;使用rarefy抽平的count ma…

牛客小白月赛93

B交换数字 题目&#xff1a; 思路&#xff1a;我们可以知道&#xff0c;a*b% mod (a%mod) * (b%mod) 代码&#xff1a; void solve(){int n;cin >> n;string a, b;cin >> a >> b;for(int i 0;i < n;i )if(a[i] > b[i])swap(a[i], b[i]);int num1…

图片无损压缩工具-VIKY

一、前言 Viky v3.4是一款功能强大的图片压缩工具&#xff0c;它能够提供高效的图片无损压缩服务。通过使用独特的压缩算法&#xff0c;该软件在显著减小图片文件大小的同时&#xff0c;还保持了图像的清晰度和色彩饱和度&#xff0c;确保了图像质量的优异表现。 二、软件特点…

AS-VJ900实时视频拼接系统产品介绍:两画面视频拼接方法和操作

目录 一、实时视频拼接系统介绍 &#xff08;一&#xff09;实时视频拼接的定义 &#xff08;二&#xff09;无缝拼接 &#xff08;三&#xff09;AS-VJ900功能介绍 1、功能 2、拼接界面介绍 二、拼接前的准备 &#xff08;一&#xff09;摄像机选择 &#xff08;二&a…

区块链 | NFT 水印:Review on Watermarking Techniques(三)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证&#xff0c;即通过使用 R S A \mathsf{RSA} RSA…

力扣每日一题37:解数独

目录 题目 大致思路 方法一&#xff1a;回溯剪枝&#xff08;正常人能想出来的&#xff09; 方法二&#xff1a;位运算优化剪枝 需要使用的位运算技巧 代码 位运算怎么就优化了呢&#xff1f; 方法三&#xff1a;枚举优化。 官解代码 方法四&#xff1a;舞蹈链算法 题…

FreeRTOS任务调度器

目录 1、什么是任务调度器 2、FreeRTOS中的任务调度器 2.1 抢占式调度 2.2 时间片调度 2.3 协作式调度 3、任务调度案例分析 3.1 实验需求 3.2 CubeMX配置 3.3 代码实现 3.3.1 uart.c 重定向printf 3.3.2 打开freertos.c并添加代码 3.3.4 代码现象 1、什么是任务调度…

7 系列 FPGA 产品介绍及选型

目录 Spartan-7 FPGAsArtix-7 FPGAsKintex-7 FPGAsVirtex-7 FPGAsFPGA芯片命名规则DSP资源BRAM资源Transceivers 资源Transceivers 总带宽I/O 个数及带宽参考文档 Spartan-7 FPGAs Artix-7 FPGAs Kintex-7 FPGAs Virtex-7 FPGAs FPGA芯片命名规则 DSP资源 BRAM资源 Transceiver…