让每一天更有质感的生活管理应用:LifeList
前言
大家好久不见啦,不知道还记得我嘛,我是云杰 。距离上次发文章已经3个月啦,这段时间里,一直在北京出差,白天在公司里紧锣密鼓赶项目进度,也是终于在10月底上线啦,进入了运维阶段。但是!作为刚毕业的大学生,晚上最是精力充沛!在这段时间里,华为激励活动很是感兴趣呀(money多多~~) 最近我上架了一款APP------必行录

在10月份的时候也是被华为审核打回------功能简单,后来也是加了一些功能才上架成功!

今天具体介绍一下------必行录
应用海报







核心卖点
- 余生时钟与动态可视化,让时间"看得见"
- 自定义清单与收藏,打造你的专属生活框架
- 频率事件一键记录,生成"痕迹",回看每次坚持
- 个人资料与头像管理,表达你自己的生活态度
- 桌面卡片联动,选中事件直达更新
- 媒体与传感器能力加持,更有温度的交互反馈
- 图片选择、生成与分享,记录生活并与朋友共享
余生时钟
-
实时计算年龄与人生统计,支持自定义退休年龄;动态 Canvas 时钟组件配合精致指针绘制。

-
示例代码(函数级注释):
ts
// 绘制主时钟:依次绘制背景、时针、分针、秒针与中心点
drawClock(context: CanvasRenderingContext2D, radius: number, canvasWidth: number, hour: number, minute: number,
second: number, time: string) {
this.drawBackGround(context, radius, canvasWidth);
this.drawHour(context, radius, hour, minute);
this.drawMinute(context, radius, minute);
this.drawSecond(context, radius, second);
this.drawDot(context);
}
ts
// 启动时钟更新:按设定间隔刷新时间并重绘Canvas
public startClock(): void {
if (this.intervalId !== 0) {
this.stopClock();
}
this.intervalId = setInterval(() => {
this.updateTime();
}, this.updateInterval);
}
自定义清单与收藏
-
支持创建、编辑、颜色选择、持久化;并提供默认清单模板提升开箱体验。

-
示例代码(函数级注释):
ts
// 添加收藏清单:避免重复ID,加入列表并持久化
public async addFavorite(favoriteData: UserSelectedFavoriteData): Promise<boolean> {
const existingIndex = this.favoriteList.findIndex(item => item.id === favoriteData.id);
if (existingIndex !== -1) {
return false;
}
this.favoriteList.unshift(favoriteData);
await this.saveFavoriteData();
return true;
}
ts
// 创建新清单:生成唯一ID,构建项目并保存为收藏
private async createNewChecklist(validItems: string[]): Promise<void> {
const checklistId = Date.now().toString();
const items: ChecklistItem[] = validItems.map((content, index) => {
return new ChecklistItem(`${checklistId}_${index + 1}`, content.trim(), false);
});
const favoriteData = new UserSelectedFavoriteData(
checklistId, this.title.trim(), this.colorOptions[this.selectedColorIndex].hex_code, items
);
await this.favoriteManager.addFavorite(favoriteData);
}
频率事件与痕迹记录
- 用于记录"喝水/跑步"等日常高频行为;提供月/总计数,自动生成痕迹用于回顾。

- 示例代码(函数级注释):
ts
// 点击事件:更新月/总计数与最近点击时间,并写入痕迹
public async clickFrequencyEvent(eventId: string): Promise<void> {
const event = this.frequencyEvents.find(e => e.id === eventId);
const now = Date.now();
const currentMonth = new Date().getMonth();
const lastClickMonth = event.lastClickTime ? new Date(event.lastClickTime).getMonth() : -1;
event.lastClickTime = now;
event.totalCount += 1;
if (currentMonth !== lastClickMonth) {
event.monthlyCount = 1;
} else {
event.monthlyCount += 1;
}
await this.saveFrequencyEvents();
await this.addToTrace(event, now);
}
个人资料与头像
- 单例管理器整合验证、存储、事件分发;支持创建、更新、导入导出。
- 示例代码(函数级注释):
ts
// 创建用户资料:校验输入、持久化保存、更新内存并广播事件
async createProfile(name: string, motto: string, avatar?: Avatar): Promise<OperationResult<UserProfile>> {
const nameValidation = UserProfileValidator.validateName(name);
const mottoValidation = UserProfileValidator.validateMotto(motto);
if (!nameValidation.isValid || !mottoValidation.isValid) {
return { success: false, message: '输入校验失败' };
}
const profile = new UserProfile(name, motto, avatar);
const saveResult = await this.storage.saveProfile(profile);
if (!saveResult) {
return { success: false, message: '保存用户资料失败' };
}
this.currentProfile = profile;
this.emitEvent({ type: UserProfileEventType.PROFILE_CREATED, profile, timestamp: Date.now() });
return { success: true, data: profile, message: '用户资料创建成功' };
}
桌面卡片联动
-
卡片转正后自动保存卡片ID并提示打开事件选择;选中事件后,表单绑定数据推送,卡片实时更新。

-
示例代码(函数级注释):
ts
// 临时卡片转正:记录formId,推送"shouldOpen"标记驱动前端打开选择页
onCastToNormalForm(formId: string) {
FormIdManager.context = this.context;
FormIdManager.addFormId(formId);
const payload = { formId: formId, shouldOpen: true };
const binding = formBindingData.createFormBindingData(payload);
formProvider.updateForm(formId, binding);
}
ts
// 更新卡片绑定:组装选中事件的展示数据并推送到卡片
public static async updateSelectedEvent(formId: string, event: FrequencyEvent, guardianIcon: string): Promise<void> {
const manager: FrequencyEventManager = FrequencyEventManager.getInstance();
const lastClickText: string = manager.getLastClickTimeText(event.id);
const payload: SelectedEventBindingData = {
eventId: event.id,
formId: formId,
eventTitle: event.title,
eventColor: event.color,
guardianIcon: guardianIcon,
monthlyCount: event.monthlyCount,
lastClickTimeText: lastClickText
};
const binding = formBindingData.createFormBindingData(payload);
await formProvider.updateForm(formId, binding);
}
媒体与传感器能力
- 点击事件完成时,播放本地音频,提供触感震动反馈,让交互更生动。
- 示例代码(函数级注释):
ts
// 播放内置音频:按状态机推进(准备→播放→释放)
async start() {
const avPlayer = await media.createAVPlayer();
avPlayer.on('stateChange', state => {
if (state === 'initialized') { avPlayer.prepare() }
else if (state === 'prepared') { avPlayer.play() }
else if (state === 'stopped') { avPlayer.release() }
});
let context = getContext(this) as common.UIAbilityContext;
let fd = await context.resourceManager.getRawFd('music01.mp3');
avPlayer.fdSrc = { fd: fd.fd, offset: fd.offset, length: fd.length };
}
ts
// 触感反馈:触发一次70ms震动增强交互体验
vibrator() {
vibrator.startVibration({ type: 'time', duration: 70 }, { id: 0, usage: 'alarm' });
}
图片选择、生成与分享
- 支持多/单选图片;余生时钟可生成图片、保存至相册,并通过系统分享面板分享至社交平台。
- 示例代码(函数级注释):
ts
// 选择图片:多选模式返回URI列表,空选返回提示
static async pickImages(context: common.UIAbilityContext, config: ImagePickerConfig = { maxSelectNumber: 9, isMultiSelect: true }): Promise<ImagePickResult> {
const photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = config.maxSelectNumber;
const photoPicker = new picker.PhotoViewPicker();
const result = await photoPicker.select(photoSelectOptions);
if (result && result.photoUris && result.photoUris.length > 0) {
return { success: true, imageUris: result.photoUris };
}
return { success: false, imageUris: [], errorMessage: '未选择任何图片' };
}
ts
// 生成并分享:生成余生时钟图片,唤起系统分享面板
private async handleShareClick(): Promise<void> {
const context = getContext(this) as common.UIAbilityContext;
const imageGenerator = new LifeClockImageGenerator(context);
const imagePath = await imageGenerator.generateLifeClockImage('mainClockContent', {
worldCups: this.lifeClockData.worldCups,
summers: this.lifeClockData.summers,
retirementYears: this.lifeClockData.retirementYears,
weekends: this.lifeClockData.weekends
});
await this.shareLifeClockImage(imagePath);
}
总结与号召
- LifeList 用更"艺术化"的方式,让时间、习惯与目标变得可视、可控、可复盘。无论是"余生时钟"的沉浸展示,还是"频率事件"的轻盈记录,亦或"自定义清单"的极致掌控,我们为每一位热爱生活的人,提供一个更懂你的日常系统。
- 立即体验,让你今天的每一次选择都被认真记录。
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯 ,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信,可以加入技术交流群。
