闹钟功能要求

展示指针表盘或数字时间。添加、修改和删除闹钟。展示闹钟列表,并可打开和关闭单个闹钟。闹钟到设定的时间后弹出提醒。将闹钟的定时数据保存到轻量级数据库。

闹钟主界面

闹钟界面包括当前时间、闹钟列表、添加闹钟子组件,具体包括以下模块:

展示当前时间。展示闹钟列表。添加闹钟。后台代理提醒。

展示当前时间

当前时间使用了Canvas组件绘制,默认展示指针表盘,点击表盘区域切换为数字时钟。效果如图所示:

在主页的ClockArea组件中初始化Canvas画布,并绑定指针表盘和数字时钟切换事件。

// ClockArea.ets

@Component

export default struct ClockArea {

build() {

Canvas(this.renderContext)

.width(this.canvasSize)

.aspectRatio(CommonConstants.DEFAULT_LAYOUT_WEIGHT)

.onReady(() => {

if (this.drawInterval === CommonConstants.DEFAULT_NUMBER_NEGATIVE) {

// 启动绘画任务

this.startDrawTask();

}

})

.onClick(() => {

this.showClock = !this.showClock;

})

}

...

// 启动绘画任务

private startDrawTask() {

let that = this;

that.renderContext.translate(

this.canvasSize / CommonConstants.DEFAULT_DOUBLE,

this.canvasSize / CommonConstants.DEFAULT_DOUBLE);

that.drawClockArea();

this.drawInterval = setInterval(() => {

that.drawClockArea();

}, MainConstant.DEFAULT_ONE_SECOND_MS);

}

}

绘画任务是使用CanvasRenderingContext2D对象在Canvas画布组件上绘制指针表盘和数字时钟。

// ClockArea.ets

// 开始绘制时钟区域

private drawClockArea(): void {

this.renderContext.clearRect(

-this.canvasSize,

-this.canvasSize / CommonConstants.DEFAULT_DOUBLE,

this.canvasSize * CommonConstants.DEFAULT_DOUBLE,

this.canvasSize);

let date = new Date();

let hours = date.getHours();

let minutes = date.getMinutes();

let seconds = date.getSeconds();

if (this.showClock) {

// 绘制表盘时钟

...

} else {

// 绘制数字时钟

...

}

}

展示闹钟列表

展示已添加的闹钟信息,可对闹钟进行启停操作,点击闹钟可跳转到闹钟操作界面(修改和删除闹钟)。主页启动后获取轻量级数据库中的闹钟定时数据,并监控数据库数据变化。

// MainViewModel.ets

public queryAlarmsTasker(callback: (alarms: Array) => void) {

let that = this;

that.queryDatabaseAlarms(callback);

let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;

preference.addPreferencesListener({

onDataChanged() {

that.queryDatabaseAlarms(callback);

}

} as PreferencesListener)

}

在AlarmList.ets中添加闹钟列表子组件,并绑定启停、跳转事件。

// AlarmList.ets

@Component

export default struct AlarmList {

@Link alarmItems: Array;

build() {

List({ space: DimensionUtil.getVp($r('app.float.alarm_list_space')) }) {

ForEach(this.alarmItems, (item: AlarmItem) => {

ListItem() {

AlarmListItem({ alarmItem: item })

}.onClick(() => {

router.pushUrl({ url: 'pages/DetailIndex', params: { alarmItem: item } });

})

}, (item: AlarmItem) => JSON.stringify(item))

}

.padding({

left: DimensionUtil.getVp($r('app.float.alarm_list_content_distance')),

right: DimensionUtil.getVp($r('app.float.alarm_list_content_distance'))

})

.listDirection(Axis.Vertical)

.layoutWeight(CommonConstants.DEFAULT_LAYOUT_WEIGHT)

.margin({ top: DimensionUtil.getVp($r('app.float.alarm_list_content_distance')) })

}

}

添加闹钟

点击界面底部闹钟添加按钮,跳转到闹钟操作界面(新增闹钟)。效果如图所示:

在MainIndex.ets中为添加按钮绑定跳转事件。

// MainIndex.ets

@Entry

@Component

struct MainIndex {

...

build() {

Column() {

...

Button() {

Image($r('app.media.ic_add')).objectFit(ImageFit.Fill)

}

...

.onClick(() => {

router.pushUrl({ url: 'pages/DetailIndex' });

})

}

...

}

}

后台代理提醒

根据闹钟列表中的数据来设置(启停)闹钟实例。

// MainViewModel.ets

// 开启/关闭闹钟

public openAlarm(id: number, isOpen: boolean) {

for (let i = 0; i < this.alarms.length; i++) {

if (this.alarms[i].id === id) {

this.alarms[i].isOpen = isOpen;

if (isOpen) {

this.reminderService.addReminder(this.alarms[i]);

} else {

this.reminderService.deleteReminder(this.alarms[i].id);

}

let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;

preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));

break;

}

}

}

闹钟详情界面

闹钟操作界面分为新增和修改界面,其中在修改界面可删除闹钟。具体包括以下模块:

退出或保存详情。设置闹钟时间。设置闹钟详情。提供后台代理提醒能力

退出或保存详情

点击左上角“x”图标关闭操作界面,关闭闹钟操作界面子组件,点击右上角“√”图标,保存当前设置并关闭操作界面。

在DetailIndex.ets入口页面中引入头部组件BackContainer,自定义了返回按钮和返回逻辑操作,添加确定(“√”)子组件,并绑定点击事件。

// BackContainer.ets

build() {

Row() {

Button() {

Image(this.backImgRes == null ? $r('app.media.ic_public_back') : this.backImgRes).objectFit(ImageFit.Fill)

}

.backgroundColor($r('app.color.trans_parent'))

.width(DimensionUtil.getVp($r('app.float.title_button_size')))

.height(DimensionUtil.getVp($r('app.float.title_button_size')))

.onClick(() => {

this.backFunc ? this.backFunc() : router.back();

})

Text(this.header)

.fontSize(DimensionUtil.getFp($r('app.float.detail_title_font_size')))

.lineHeight(DimensionUtil.getVp($r('app.float.title_line_height')))

.margin({ left: DimensionUtil.getVp($r('app.float.title_margin')) })

.fontColor($r('app.color.grey_divider'))

.fontWeight(FontWeight.Bold)

Blank()

if (this.closer) {

this.closer();

}

}

.padding({

left: DimensionUtil.getVp($r('app.float.title_horizon_margin')),

right: DimensionUtil.getVp($r('app.float.title_horizon_margin'))

})

.height(DimensionUtil.getVp($r('app.float.page_title_height')))

.width(CommonConstants.FULL_LENGTH)

}

设置闹钟时间

设置闹钟提醒时间,在闹钟操作界面可通过滑动选择器设置闹钟的提醒时间(包括:时段、小时、分钟)。详情页DetailIndex.ets中添加闹钟时间选择器子组件DatePickArea.ets。

// DatePickArea.ets

@Component

export default struct DatePickArea {

build() {

Stack({ alignContent: Alignment.Center }) {

Row() {

ForEach(DetailConstant.DAY_DATA, (item: DayDataItem) => {

TextPicker({ range: item.data, selected: item.delSelect })

.layoutWeight(CommonConstants.DEFAULT_LAYOUT_WEIGHT)

.backgroundColor($r('app.color.grey_light'))

.onChange((value: string, index: number) => {

item.delSelect = index;

})

}, (item: DayDataItem) => JSON.stringify(item))

}

}

.height(DimensionUtil.getVp($r('app.float.date_picker_height')))

.padding({

left: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon')),

right: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon'))

})

}

}

设置闹钟时间

设置闹钟提醒时间,在闹钟操作界面可通过滑动选择器设置闹钟的提醒时间(包括:时段、小时、分钟)。详情页DetailIndex.ets中添加闹钟时间选择器子组件DatePickArea.ets。

// DatePickArea.ets

@Component

export default struct DatePickArea {

build() {

Stack({ alignContent: Alignment.Center }) {

Row() {

ForEach(DetailConstant.DAY_DATA, (item: DayDataItem) => {

TextPicker({ range: item.data, selected: item.delSelect })

.layoutWeight(CommonConstants.DEFAULT_LAYOUT_WEIGHT)

.backgroundColor($r('app.color.grey_light'))

.onChange((value: string, index: number) => {

item.delSelect = index;

})

}, (item: DayDataItem) => JSON.stringify(item))

}

}

.height(DimensionUtil.getVp($r('app.float.date_picker_height')))

.padding({

left: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon')),

right: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon'))

})

}

}

设置闹钟详情

// SettingItem.ets

build() {

Column() {

ForEach(this.settingInfo, (item: AlarmSettingItem, index: number | undefined) => {

Divider()

...

Row() {

Text(item.title)

...

Text(item.content)

...

Image($r('app.media.ic_right'))

...

}

...

.onClick(() => {

this.showSettingDialog(item.sType);

})

}, (item: AlarmSettingItem, index: number | undefined) => JSON.stringify(item) + index)

}

...

}

提供后台代理提醒能力

导入系统提醒服务类ReminderService.ets,它由系统后台代理提醒能力封装,支持新增、修改、删除系统闹钟功能,在设置、删除闹钟后同步更新到轻量级数据库中并刷新主页页面。

// DetailViewModel.ets

public async setAlarmRemind(alarmItem: AlarmItem) {

alarmItem.hour = this.getAlarmTime(CommonConstants.DEFAULT_SINGLE);

alarmItem.minute = this.getAlarmTime(CommonConstants.DEFAULT_DATA_PICKER_HOUR_SELECTION);

let index = await this.findAlarmWithId(alarmItem.id);

if (index !== CommonConstants.DEFAULT_NUMBER_NEGATIVE) {

// 已存在,删除原有提醒

this.reminderService.deleteReminder(alarmItem.id);

} else {

// 不存在,以数据长度为notificationId新增闹钟数据

index = this.alarms.length;

alarmItem.notificationId = index;

this.alarms.push(alarmItem);

}

this.reminderService.addReminder(alarmItem, (newId: number) => {

alarmItem.id = newId;

alarmItem.isOpen = true;

this.alarms[index] = alarmItem;

let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;

preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));

})

}

public async removeAlarmRemind(id: number) {

this.reminderService.deleteReminder(id);

let index = await this.findAlarmWithId(id);

if (index !== CommonConstants.DEFAULT_NUMBER_NEGATIVE) {

this.alarms.splice(index, CommonConstants.DEFAULT_SINGLE);

}

let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;

preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));

}

全文是对鸿蒙开发的技术运用,更多的鸿蒙开发实战技术,可以前往主页查看更多信息。分享一份鸿蒙的学习路线图(略缩版),高清完整版在主页找我保存。

最后

实现一个简易闹钟效果图:

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: