案例效果
资源文件与初始化
string.json
{
"string": [
{
"name": "entry_desc",
"value": "description"
},
{
"name": "entryAbility_desc",
"value": "description"
},
{
"name": "entryAbility_label",
"value": "List_HDC"
},
{
"name": "task_morning",
"value": "早起"
},
{
"name": "task_water",
"value": "喝水"
},
{
"name": "task_apple",
"value": "吃苹果"
},
{
"name": "task_smile",
"value": "每日微笑"
},
{
"name": "task_brush",
"value": "每日刷牙"
},
{
"name": "task_night",
"value": "早睡"
},
{
"name": "already_open",
"value": "已开启"
},
{
"name": "complete",
"value": "完成"
},
{
"name": "frequency",
"value": "频率"
},
{
"name": "remind_time",
"value": "提醒时间"
},
{
"name": "open_reminder",
"value": "开启提醒"
},
{
"name": "target_setting",
"value": "目标设置"
},
{
"name": "cancel",
"value": "取消"
},
{
"name": "confirm",
"value": "确认"
},
{
"name": "set_your_frequency",
"value": "请设置您的频率"
}
]
}
color.json
{
"color": [
{
"name": "white",
"value": "#FFFFFF"
},
{
"name": "primaryBgColor",
"value": "#F1F3F5"
},
{
"name": "titleColor",
"value": "#182431"
},
{
"name": "btnBgColor",
"value": "#F2F2F2"
},
{
"name": "statusTipColor",
"value": "#989A9C"
},
{
"name": "blueColor",
"value": "#007DFF"
},
{
"name": "black",
"value": "#000000"
},
{
"name": "primaryRed",
"value": "#E92F4F"
},
{
"name": "tabTitleColor",
"value": "#999"
},
{
"name": "signatureColor",
"value": "#66686a"
},
{
"name": "leveColor",
"value": "#c99411"
},
{
"name": "leveBgColor",
"value": "#d4e6f1"
},
{
"name": "borderColor",
"value": "#cccccc"
},
{
"name": "mineBgColor",
"value": "#edf2f5"
},
{
"name": "launcherBlueColor",
"value": "#4694C2"
},
{
"name": "disabledColor",
"value": "#dddadc"
}
]
}
CommonConstant
// ets/common/contants/CommonConstant.ets
export const THOUSANDTH_80: string = '8%'
export const THOUSANDTH_100: string = '10%'
export const THOUSANDTH_400: string = '40%'
export const THOUSANDTH_500: string = '50%'
export const THOUSANDTH_560: string = '56%'
export const THOUSANDTH_800: string = '80%'
export const THOUSANDTH_900: string = '90%'
export const THOUSANDTH_940: string = '94%'
export const THOUSANDTH_1000: string = '100%'
export const DEFAULT_2: number = 2
export const DEFAULT_8: number = 8
export const DEFAULT_12: number = 12
export const DEFAULT_10: number = 10
export const DEFAULT_16: number = 16
export const DEFAULT_18: number = 18
export const DEFAULT_20: number = 20
export const DEFAULT_24: number = 24
export const DEFAULT_28: number = 28
export const DEFAULT_32: number = 32
export const DEFAULT_48: number = 48
export const DEFAULT_56: number = 56
export const DEFAULT_60: number = 60
export const LIST_ITEM_SPACE: number = 2
export const ADD_TASK_TITLE: string = '添加任务'
export const EDIT_TASK_TITLE: string = '编辑任务'
export const SETTING_FINISHED_MESSAGE = '设置完成!!!'
export const CHOOSE_TIME_OUT_RANGE: string = '选择时间超出范围'
export const TODAY: string = new Date().toDateString()
export const DEFAULT_TIME: string = '08:00'
export const GET_UP_TIME_RANGE: string = '(06:00 - 09:00)'
export const SLEEP_TIME_RANGE: string = '(20:00 - 23:00)'
export const GET_UP_EARLY_TIME: string = '06:00'
export const GET_UP_LATE_TIME: string = '09:00'
export const SLEEP_EARLY_TIME: string = '20:00'
export const SLEEP_LATE_TIME: string = '23:00'
export const DEFAULT_SELECTED_TIME: Date = new Date(`${TODAY} 8:00:00`)
export const EVERYDAY: string = '每天'
export const NO_LENGTH: number = 0
export const INIT_WEEK_IDS: string = '1, 2, 3, 4, 5, 6, 7'
export const PER_DAY: string = '/ 天'
export const ZERO: number = 0
export const MINUS_20: number = -20
export const HAS_NO_INDEX: number = -1
export const DRINK_STEP: number = 25
export const DRINK_MAX_RANGE: number = 500
export const TIMES_100: number = 100
export const EAT_APPLE_RANGE: number = 100
export const DEFAULT_TEXT: string = '0.25'
export const DEFAULT_APPLE: string = '1'
添加任务
首页组件
// ets/pages/Index.ets
import TaskList from '../view/TaskList'
import { TaskListItem, TaskInitList } from '../model/TaskInitList'
import { THOUSANDTH_1000, ADD_TASK_TITLE } from '../common/constants/CommonConstant'
@Entry
@Component
struct Index {
@Provide taskList: TaskListItem[] = TaskInitList
build() {
Row() {
Navigation() {
Column() {
TaskList()
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.Center)
}
.size({ width: THOUSANDTH_1000, height: THOUSANDTH_1000 })
.title(ADD_TASK_TITLE)
.titleMode(NavigationTitleMode.Mini)
}
.backgroundColor($r('app.color.primaryBgColor'))
.height(THOUSANDTH_1000)
}
}
任务列表初始化
// ets/model/TaskInitList.ets
export interface TaskListItem {
taskID: number
taskName: Resource
isOpen: boolean
unit: string
icon: Resource
targetValue: string
isAlarm: boolean
startTime: string
frequency: string
}
export interface FrequencyContentType {
id: number,
label: string,
isChecked: boolean
}
export const TaskInitList: TaskListItem[] = [
{ // Get up early.
taskID: 1,
taskName: $r('app.string.task_morning'),
icon: $r('app.media.morning'),
targetValue: '08: 00',
isOpen: true,
unit: '',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
},
{ // Drink water.
taskID: 2,
taskName: $r('app.string.task_water'),
icon: $r('app.media.water'),
targetValue: '0.25',
isOpen: true,
unit: 'L',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
},
{ // Eat apples.
taskID: 3,
taskName: $r('app.string.task_apple'),
icon: $r('app.media.apple'),
targetValue: '1',
isOpen: true,
unit: '个',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
},
{ // Smile every day.
taskID: 4,
taskName: $r('app.string.task_smile'),
icon: $r('app.media.smile'),
targetValue: '1',
isOpen: false,
unit: '次',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
},
{ // Clean one’s teeth.
taskID: 5,
taskName: $r('app.string.task_brush'),
icon: $r('app.media.brush'),
targetValue: '1',
isOpen: false,
unit: '次',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
},
{ // Go to bed early.
taskID: 6,
taskName: $r('app.string.task_night'),
icon: $r('app.media.night'),
targetValue: '20: 00',
isOpen: false,
unit: '',
isAlarm: false,
startTime: '08: 00',
frequency: '1, 2, 3, 4, 5, 6, 7'
}
]
任务列表视图
// ets/view/TaskList.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
@Component
export default struct TaskList {
@Consume taskList: TaskListItem[]
build() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ForEach(this.taskList, (item: TaskListItem) => {
ListItem() {
Row() {
Row() {
Image(item?.icon)
.width(commonConst.DEFAULT_24)
.height(commonConst.DEFAULT_24)
.margin({ right: commonConst.DEFAULT_8 })
Text(item?.taskName)
.fontSize(commonConst.DEFAULT_20)
.fontColor($r('app.color.titleColor'))
}
.width(commonConst.THOUSANDTH_500)
Blank()
.layoutWeight(1)
if (item?.isOpen) {
Text($r('app.string.already_open'))
.fontSize(commonConst.DEFAULT_16)
.flexGrow(1)
.align(Alignment.End)
.margin({ right: commonConst.DEFAULT_8 })
.fontColor($r('app.color.titleColor'))
}
Image($r('app.media.right_grey'))
.width(commonConst.DEFAULT_8)
.height(commonConst.DEFAULT_16)
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
.height(commonConst.THOUSANDTH_80)
.borderRadius(commonConst.DEFAULT_12)
.backgroundColor($r('app.color.white'))
})
}
.height(commonConst.THOUSANDTH_1000)
.width(commonConst.THOUSANDTH_940)
}
}
任务编辑页
添加跳转
// ets/view/TaskList.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import { router } from '@kit.ArkUI'
import { formatParams } from '../viewModel/TaskTargetSetting'
@Component
export default struct TaskList {
@Consume taskList: TaskListItem[]
build() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ForEach(this.taskList, (item: TaskListItem) => {
ListItem() {
Row() {
Row() {
Image(item?.icon)
.width(commonConst.DEFAULT_24)
.height(commonConst.DEFAULT_24)
.margin({ right: commonConst.DEFAULT_8 })
Text(item?.taskName)
.fontSize(commonConst.DEFAULT_20)
.fontColor($r('app.color.titleColor'))
}
.width(commonConst.THOUSANDTH_500)
Blank()
.layoutWeight(1)
if (item?.isOpen) {
Text($r('app.string.already_open'))
.fontSize(commonConst.DEFAULT_16)
.flexGrow(1)
.align(Alignment.End)
.margin({ right: commonConst.DEFAULT_8 })
.fontColor($r('app.color.titleColor'))
}
Image($r('app.media.right_grey'))
.width(commonConst.DEFAULT_8)
.height(commonConst.DEFAULT_16)
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
.height(commonConst.THOUSANDTH_80)
.borderRadius(commonConst.DEFAULT_12)
.backgroundColor($r('app.color.white'))
// 1. 添加链接
.onClick(() => {
router.pushUrl({
url: 'pages/TaskEditPage',
params: {
params: formatParams(item)
}
})
})
})
}
.height(commonConst.THOUSANDTH_1000)
.width(commonConst.THOUSANDTH_940)
}
}
任务目标设置模型(formatParams)
// ets/viewModel/TaskTargetSetting
import { TaskListItem } from '../model/TaskInitList'
export const formatParams = (params: TaskListItem) => {
return JSON.stringify(params)
}
编辑页面
// ets/pages/TaskEditPage.ets
import { THOUSANDTH_1000, EDIT_TASK_TITLE } from '../common/constants/CommonConstant'
import TaskDetail from '../view/TaskDetail'
@Entry
@Component
struct TaskEdit {
build() {
Row() {
Navigation() {
Column() {
TaskDetail()
}
.width(THOUSANDTH_1000)
.height(THOUSANDTH_1000)
}
.size({ width: THOUSANDTH_1000, height: THOUSANDTH_1000 })
.title(EDIT_TASK_TITLE)
.titleMode(NavigationTitleMode.Mini)
}
.height(THOUSANDTH_1000)
.backgroundColor($r('app.color.primaryBgColor'))
}
}
详情页
// ets/view/TaskDetail.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {
TaskChooseItem
} from './TaskEditListItem'
import { router } from '@kit.ArkUI'
@Styles
function listItemStyle() {
.backgroundColor($r('app.color.white'))
.height(commonConst.DEFAULT_56)
.borderRadius(commonConst.DEFAULT_10)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
@Component
export default struct TaskDetail {
@Provide settingParams: TaskListItem = this.parseRouterParams()
parseRouterParams() {
let params = router.getParams() as Record<string, Object>
const routerParams: TaskListItem = JSON.parse(params.params as string)
return routerParams
}
build() {
Column() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
.listItemStyle()
}
}
.width(commonConst.THOUSANDTH_1000)
}
}
任务编辑列表项
// ets/view/TaskEditListItem.ets
import { TaskListItem } from '../model/TaskInitList'
import {
DEFAULT_20,
DEFAULT_32,
DEFAULT_56,
THOUSANDTH_1000,
} from '../common/constants/CommonConstant'
@Component
export struct TaskChooseItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text(this.settingParams.taskName).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams.isOpen })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isOpen = isOn;
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
目标设置展示
引入目标设置
// ets/view/TaskDetail.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {
TaskChooseItem,
// 2. 引入TargetSetItem
TargetSetItem
} from './TaskEditListItem'
import { router } from '@kit.ArkUI'
import { taskType } from '../model/TaskInfo'
@Styles
function listItemStyle() {
.backgroundColor($r('app.color.white'))
.height(commonConst.DEFAULT_56)
.borderRadius(commonConst.DEFAULT_10)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
@Component
export default struct TaskDetail {
@Provide settingParams: TaskListItem = this.parseRouterParams()
parseRouterParams() {
let params = router.getParams() as Record<string, Object>
const routerParams: TaskListItem = JSON.parse(params.params as string)
return routerParams
}
build() {
Column() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
.listItemStyle()
// 1. 目标设置入口
ListItem() {
TargetSetItem()
}
.listItemStyle()
.enabled(
this.settingParams?.isOpen &&
(this.settingParams?.taskID !== taskType.smile) &&
(this.settingParams?.taskID !== taskType.brushTeeth)
)
}
.width(commonConst.THOUSANDTH_940)
}
.width(commonConst.THOUSANDTH_1000)
}
}
目标设置展示实现
// ets/view/TaskEditListItem.ets
import { TaskListItem } from '../model/TaskInitList'
import {
DEFAULT_16,
DEFAULT_20,
DEFAULT_32,
DEFAULT_56,
DEFAULT_8,
PER_DAY,
THOUSANDTH_1000,
} from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
// 2.定义公共样式targetSetCommon
@Extend(Text)
function targetSetCommon() {
.fontSize(DEFAULT_16)
.flexGrow(1)
.margin({ right: DEFAULT_8 })
.align(Alignment.End)
}
// 2.定义公共样式targetSettingStyle
@Extend(Text)
function targetSettingStyle(isOpen: boolean, taskID: number) {
.fontColor(isOpen && taskID !== taskType.smile && taskID !== taskType.brushTeeth ?
$r('app.color.titleColor') :
$r('app.color.disabledColor'))
}
@Component
export struct TaskChooseItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text(this.settingParams.taskName).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams.isOpen })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isOpen = isOn;
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
// 1. 定义TargetSetItem组件
@Component
export struct TargetSetItem {
@Consume settingParams: TaskListItem;
build() {
Row() {
Text($r('app.string.target_setting'))
.fontSize(DEFAULT_20)
.fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
if (this.settingParams?.unit === '') {
Text(`${this.settingParams?.targetValue}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
} else {
Text(`${this.settingParams?.targetValue} ${this.settingParams?.unit} ${PER_DAY}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
}
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16);
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
TaskInfo 枚举模型设置
// ets/model/TaskInfo.ets
export enum taskType {
'getup' = 1,
'drinkWater',
'eatApple',
'smile',
'brushTeeth',
'sleepEarly'
}
弹窗构造逻辑
定义单击事件
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {
TaskChooseItem,
TargetSetItem
} from './TaskEditListItem'
import { router } from '@kit.ArkUI'
import { taskType } from '../model/TaskInfo'
// 4. 引入BroadCast(先去创建)
import { BroadCast, BroadCastType } from '../common/utils/BroadCast'
import { CustomDialogView } from './CustomDialogView'
@Styles
function listItemStyle() {
.backgroundColor($r('app.color.white'))
.height(commonConst.DEFAULT_56)
.borderRadius(commonConst.DEFAULT_10)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
@Component
export default struct TaskDetail {
@Provide settingParams: TaskListItem = this.parseRouterParams()
// 5. 提供 broadCast
@Provide broadCast: BroadCast = new BroadCast()
parseRouterParams() {
let params = router.getParams() as Record<string, Object>
const routerParams: TaskListItem = JSON.parse(params.params as string)
return routerParams
}
// 7. 先去定义弹窗和builder,注册(on)完,这里解绑
aboutToAppear() {
this.broadCast.off()
}
build() {
Column() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
.listItemStyle()
ListItem() {
TargetSetItem()
}
.listItemStyle()
// 3. 设置 smile & brushTeeth 不可单击
.enabled(
this.settingParams?.isOpen &&
(this.settingParams?.taskID !== taskType.smile) &&
(this.settingParams?.taskID !== taskType.brushTeeth)
)
// 1. 定义单击事件
.onClick(() => {
// 2. 测试单击,目的是引出第 3 步
// console.log('test')
// 8. 最后再触发
this.broadCast.emit(
BroadCastType.SHOW_TARGET_SETTING_DIALOG)
})
// 9. 测试提醒时间设置
ListItem() {
Text('提醒时间')
}
.listItemStyle()
.enabled(this.settingParams?.isOpen && this.settingParams?.isAlarm)
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_REMIND_TIME_DIALOG
)
})
// 9. 测试频率设置
ListItem() {
Text('频率')
}
.listItemStyle()
.enabled(this.settingParams?.isOpen)
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_FREQUENCY_DIALOG
)
})
}
// 6.定义弹框视图(先去创建)
CustomDialogView()
}
.width(commonConst.THOUSANDTH_1000)
}
}
定义 BroadCast
// ets/common/util/BroadCast.ets
export class BroadCast {
private callBackArray = []
public on(event: string, callback: Function) {
(this.callBackArray[event] || (this.callBackArray[event] = [])).push(callback)
}
public off() {
this.callBackArray = []
}
public emit(event: string) {
let _self = this
if (!this.callBackArray[event]) {
return
}
let cbs: Function[] = this.callBackArray[event]
if (cbs) {
let len = cbs.length;
for (let i = 0; i < len; i++) {
try {
cbs[i](_self)
} catch (e) {
new Error(e)
}
}
}
}
}
export enum BroadCastType {
SHOW_TARGET_SETTING_DIALOG = 'showTargetSettingDialog',
SHOW_REMIND_TIME_DIALOG = 'showRemindTimeDialog',
SHOW_FREQUENCY_DIALOG = 'showFrequencyDialog'
}
定义弹窗视图
// ets/view/CustomDialogView.ets
import { TargetSettingDialog, RemindTimeDialog, FrequencyDialog } from './TaskSettingDialog'
import { BroadCast, BroadCastType } from '../common/utils/BroadCast'
import { ZERO, MINUS_20 } from '../common/constants/CommonConstant'
@Component
export struct CustomDialogView {
@State isShow: boolean = false
@Provide achievementLevel: number = 3
@Consume broadCast: BroadCast
targetSettingDialogController: CustomDialogController = new CustomDialogController({
builder: TargetSettingDialog(),
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: ZERO, dy: MINUS_20 }
})
RemindTimeDialogController: CustomDialogController = new CustomDialogController({
builder: RemindTimeDialog(),
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: ZERO, dy: MINUS_20 }
});
FrequencyDialogController: CustomDialogController = new CustomDialogController({
builder: FrequencyDialog(),
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: ZERO, dy: MINUS_20 }
})
aboutToAppear() {
let self = this
this.broadCast.on(
BroadCastType.SHOW_TARGET_SETTING_DIALOG,
() => {
self.targetSettingDialogController.open()
})
this.broadCast.on(
BroadCastType.SHOW_REMIND_TIME_DIALOG,
() => {
self.RemindTimeDialogController.open()
})
this.broadCast.on(
BroadCastType.SHOW_FREQUENCY_DIALOG,
() => {
self.FrequencyDialogController.open()
})
}
build() {
}
}
定义弹窗 builder 组件
// ets/view/TaskSettingDialog.ets
import * as commonConst from '../common/constants/CommonConstant'
@CustomDialog
export struct TargetSettingDialog {
controller: CustomDialogController = new CustomDialogController({
builder: TargetSettingDialog()
})
build() {
Column() {
Text('target setting dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct RemindTimeDialog {
controller: CustomDialogController = new CustomDialogController({
builder: RemindTimeDialog()
})
build() {
Column() {
Text('remind time dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct FrequencyDialog {
controller: CustomDialogController = new CustomDialogController({
builder: FrequencyDialog()
})
build() {
Column() {
Text('frequency dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
目标设置弹窗实现
目标设置窗口逻辑
// ets/view/TaskSettingDialog.ets
import * as commonConst from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
import { TaskListItem } from '../model/TaskInitList'
import { createAppleRange, createDrinkRange, formatTime, returnTimeStamp } from '../viewModel/TaskTargetSetting'
import { promptAction } from '@kit.ArkUI'
@CustomDialog
export struct TargetSettingDialog {
controller: CustomDialogController = new CustomDialogController({
builder: TargetSettingDialog()
})
@Consume settingParams: TaskListItem
currentTime: string = commonConst.DEFAULT_TIME
currentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :
commonConst.DEFAULT_APPLE
drinkRange: string[] = createDrinkRange()
appleRange: string[] = createAppleRange()
createSubTitle() {
if (this.settingParams.taskID === taskType.getup) {
return commonConst.GET_UP_TIME_RANGE
}
if (this.settingParams.taskID === taskType.sleepEarly) {
return commonConst.SLEEP_TIME_RANGE
}
return ''
}
setTargetValue() {
if (this.settingParams.taskID === taskType.getup) {
if (!this.compareTime(commonConst.GET_UP_EARLY_TIME, commonConst.GET_UP_LATE_TIME)) {
return
}
this.settingParams.targetValue = this.currentTime
return
}
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
}
compareTime(startTime: string, endTime: string) {
if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) ||
returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {
promptAction.showToast({
message: commonConst.CHOOSE_TIME_OUT_RANGE
})
return false
}
return true
}
build() {
Column() {
Row() {
Text($r('app.string.target_setting')).fontSize(commonConst.DEFAULT_20).margin({ right: commonConst.DEFAULT_12 })
Text(this.createSubTitle())
.fontSize(commonConst.DEFAULT_16)
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.Start)
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams.taskID) > commonConst.HAS_NO_INDEX) {
TimePicker({
selected: commonConst.DEFAULT_SELECTED_TIME
})
.height(commonConst.THOUSANDTH_800)
.useMilitaryTime(true)
.onChange((value: TimePickerResult) => {
this.currentTime = formatTime(value)
})
} else {
TextPicker({ range: this.settingParams.taskID === taskType.drinkWater ? this.drinkRange : this.appleRange,
value: this.settingParams.targetValue })
.width(commonConst.THOUSANDTH_900)
.height(commonConst.THOUSANDTH_800)
.onChange((value: string | string[]) => {
this.currentValue = (value as string)?.split(' ')[0]
})
}
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.currentTime = commonConst.DEFAULT_TIME
this.currentValue = commonConst.DEFAULT_TEXT
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.setTargetValue()
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_1000)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_20 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct RemindTimeDialog {
controller: CustomDialogController = new CustomDialogController({
builder: RemindTimeDialog()
})
build() {
Column() {
Text('remind time dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct FrequencyDialog {
controller: CustomDialogController = new CustomDialogController({
builder: FrequencyDialog()
})
build() {
Column() {
Text('frequency dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
任务目标设置视图模型
// ets/TaskTargetSetting.ets
import { DRINK_MAX_RANGE, DRINK_STEP, EAT_APPLE_RANGE, TIMES_100, TODAY } from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import { padTo2Digits } from './FrequencySetting'
export const formatParams = (params: TaskListItem) => {
return JSON.stringify(params)
}
export const formatTime = (value: TimePickerResult) => {
let hour: number = 0
let minute: number = 0
if (value.hour !== undefined && value.minute !== undefined) {
hour = value.hour
minute = value.minute
}
return `${padTo2Digits(hour)}:${padTo2Digits(minute)}`
}
export const createDrinkRange = () => {
const drinkRangeArr: string[] = []
for (let i = DRINK_STEP; i <= DRINK_MAX_RANGE; i += DRINK_STEP) {
drinkRangeArr.push(`${i / TIMES_100} L`)
}
return drinkRangeArr
}
export const createAppleRange = () => {
const appleRangeArr: string[] = []
for (let i = 1; i <= EAT_APPLE_RANGE; i++) {
appleRangeArr.push(`${i} 个`)
}
return appleRangeArr
}
export const returnTimeStamp = (currentTime: string) => {
const timeString = `${TODAY} ${currentTime}`
return new Date(timeString).getTime()
}
频率设置视图模型
// ets/viewModel/FrequencySetting.ets
export function padTo2Digits(num: number) {
return num.toString().padStart(2, '0')
}
时间提醒弹窗实现
更新TaskDetail
// ets/view/TaskDetail.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {
TaskChooseItem,
TargetSetItem,
// 3. 导入模块
OpenRemindItem,
RemindTimeItem
} from './TaskEditListItem'
import { router } from '@kit.ArkUI'
import { taskType } from '../model/TaskInfo'
import { BroadCast, BroadCastType } from '../common/utils/BroadCast'
import { CustomDialogView } from './CustomDialogView'
@Styles
function listItemStyle() {
.backgroundColor($r('app.color.white'))
.height(commonConst.DEFAULT_56)
.borderRadius(commonConst.DEFAULT_10)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
@Component
export default struct TaskDetail {
@Provide settingParams: TaskListItem = this.parseRouterParams()
@Provide broadCast: BroadCast = new BroadCast()
parseRouterParams() {
let params = router.getParams() as Record<string, Object>
const routerParams: TaskListItem = JSON.parse(params.params as string)
return routerParams
}
aboutToAppear() {
this.broadCast.off()
}
build() {
Column() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
.listItemStyle()
ListItem() {
TargetSetItem()
}
.listItemStyle()
.enabled(
this.settingParams?.isOpen &&
(this.settingParams?.taskID !== taskType.smile) &&
(this.settingParams?.taskID !== taskType.brushTeeth)
)
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_TARGET_SETTING_DIALOG)
})
// 1.构造编辑列表相应内容
ListItem() {
OpenRemindItem()
}
.listItemStyle()
.enabled(this.settingParams.isOpen)
ListItem() {
// 2.构造编辑列表相应内容
RemindTimeItem()
}
.listItemStyle()
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_REMIND_TIME_DIALOG
)
})
ListItem() {
Text('频率')
}
.listItemStyle()
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_FREQUENCY_DIALOG
)
})
}
CustomDialogView()
}
.width(commonConst.THOUSANDTH_1000)
}
}
实现编辑任务列表的开启提醒与提醒时间
import { TaskListItem } from '../model/TaskInitList'
import {
DEFAULT_16,
DEFAULT_20,
DEFAULT_32,
DEFAULT_56,
DEFAULT_8,
PER_DAY,
THOUSANDTH_1000,
} from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
@Extend(Text)
function targetSetCommon() {
.fontSize(DEFAULT_16)
.flexGrow(1)
.margin({ right: DEFAULT_8 })
.align(Alignment.End)
}
@Extend(Text)
function targetSettingStyle(isOpen: boolean, taskID: number) {
.fontColor(isOpen && taskID !== taskType.smile && taskID !== taskType.brushTeeth ?
$r('app.color.titleColor') :
$r('app.color.disabledColor'))
}
@Extend(Text)
function remindTimeStyle(isOpen: boolean, isAlarm: boolean) {
.fontColor(isOpen && isAlarm ? $r('app.color.titleColor') : $r('app.color.disabledColor'))
}
@Component
export struct TaskChooseItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text(this.settingParams.taskName).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams.isOpen })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isOpen = isOn;
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Component
export struct TargetSetItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.target_setting'))
.fontSize(DEFAULT_20)
.fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
if (this.settingParams?.unit === '') {
Text(`${this.settingParams?.targetValue}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
} else {
Text(`${this.settingParams?.targetValue} ${this.settingParams?.unit} ${PER_DAY}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
}
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16);
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
// 1.实现开启提醒
@Component
export struct OpenRemindItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.open_reminder'))
.fontSize(DEFAULT_20)
.fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams?.isAlarm })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isAlarm = isOn
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
// 2.实现提醒时间
@Component
export struct RemindTimeItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.remind_time')).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
Text(this.settingParams?.startTime)
.targetSetCommon()
.remindTimeStyle(this.settingParams.isOpen, this.settingParams.isAlarm)
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16)
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
实现时间提醒弹窗
import * as commonConst from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
import { TaskListItem } from '../model/TaskInitList'
import { createAppleRange, createDrinkRange, formatTime, returnTimeStamp } from '../viewModel/TaskTargetSetting'
import { promptAction } from '@kit.ArkUI'
@CustomDialog
export struct TargetSettingDialog {
controller: CustomDialogController = new CustomDialogController({
builder: TargetSettingDialog()
})
@Consume settingParams: TaskListItem
currentTime: string = commonConst.DEFAULT_TIME
currentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :
commonConst.DEFAULT_APPLE
drinkRange: string[] = createDrinkRange()
appleRange: string[] = createAppleRange()
createSubTitle() {
if (this.settingParams.taskID === taskType.getup) {
return commonConst.GET_UP_TIME_RANGE
}
if (this.settingParams.taskID === taskType.sleepEarly) {
return commonConst.SLEEP_TIME_RANGE
}
return ''
}
setTargetValue() {
if (this.settingParams.taskID === taskType.getup) {
if (!this.compareTime(commonConst.GET_UP_EARLY_TIME, commonConst.GET_UP_LATE_TIME)) {
return
}
this.settingParams.targetValue = this.currentTime
return
}
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
}
compareTime(startTime: string, endTime: string) {
if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) ||
returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {
promptAction.showToast({
message: commonConst.CHOOSE_TIME_OUT_RANGE
})
return false
}
return true
}
build() {
Column() {
Row() {
Text($r('app.string.target_setting')).fontSize(commonConst.DEFAULT_20).margin({ right: commonConst.DEFAULT_12 })
Text(this.createSubTitle())
.fontSize(commonConst.DEFAULT_16)
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.Start)
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams.taskID) > commonConst.HAS_NO_INDEX) {
TimePicker({
selected: commonConst.DEFAULT_SELECTED_TIME
})
.height(commonConst.THOUSANDTH_800)
.useMilitaryTime(true)
.onChange((value: TimePickerResult) => {
this.currentTime = formatTime(value)
})
} else {
TextPicker({ range: this.settingParams?.taskID === taskType.drinkWater ? this.drinkRange : this.appleRange,
value: this.settingParams.targetValue })
.width(commonConst.THOUSANDTH_900)
.height(commonConst.THOUSANDTH_800)
.onChange((value: string | string[]) => {
this.currentValue = (value as string)?.split(' ')[0]
})
}
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.currentTime = commonConst.DEFAULT_TIME;
this.currentValue = commonConst.DEFAULT_TEXT;
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.setTargetValue()
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_1000)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_20 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
// 实现时间提醒弹窗
@CustomDialog
export struct RemindTimeDialog {
controller: CustomDialogController = new CustomDialogController({
builder: RemindTimeDialog()
})
currentTime: string = commonConst.DEFAULT_TIME
@Consume settingParams: TaskListItem
build() {
Column() {
Column() {
Text($r('app.string.remind_time'))
.fontSize(commonConst.DEFAULT_20)
.margin({ top: commonConst.DEFAULT_10 })
.width(commonConst.THOUSANDTH_1000)
.textAlign(TextAlign.Start)
}
.width(commonConst.THOUSANDTH_900)
TimePicker({
selected: commonConst.DEFAULT_SELECTED_TIME
})
.height(commonConst.THOUSANDTH_800)
.useMilitaryTime(true)
.onChange((value: TimePickerResult) => {
this.currentTime = formatTime(value)
})
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.currentTime = commonConst.DEFAULT_TIME
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.settingParams.startTime = this.currentTime
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_1000)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_20 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct FrequencyDialog {
controller: CustomDialogController = new CustomDialogController({
builder: FrequencyDialog()
})
build() {
Column() {
Text('frequency dialog')
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
频率弹窗和提交完成的实现
// ets/view/TaskDetail.ets
import * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {
TaskChooseItem,
TargetSetItem,
OpenRemindItem,
RemindTimeItem,
FrequencyItem
} from './TaskEditListItem'
import { promptAction, router } from '@kit.ArkUI'
import { taskType } from '../model/TaskInfo'
import { BroadCast, BroadCastType } from '../common/utils/BroadCast'
import { CustomDialogView } from './CustomDialogView'
@Styles
function listItemStyle() {
.backgroundColor($r('app.color.white'))
.height(commonConst.DEFAULT_56)
.borderRadius(commonConst.DEFAULT_10)
.padding({ left: commonConst.DEFAULT_12, right: commonConst.DEFAULT_12 })
}
@Component
export default struct TaskDetail {
@Provide settingParams: TaskListItem = this.parseRouterParams()
@Provide broadCast: BroadCast = new BroadCast()
@Provide frequency: string = commonConst.EVERYDAY
parseRouterParams() {
let params = router.getParams() as Record<string, Object>
const routerParams: TaskListItem = JSON.parse(params.params as string)
return routerParams
}
aboutToAppear() {
this.broadCast.off()
}
finishTaskEdit() {
promptAction.showToast({
message: commonConst.SETTING_FINISHED_MESSAGE
})
}
build() {
Column() {
List({ space: commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
.listItemStyle()
ListItem() {
TargetSetItem()
}
.listItemStyle()
.enabled(
this.settingParams?.isOpen &&
(this.settingParams?.taskID !== taskType.smile) &&
(this.settingParams?.taskID !== taskType.brushTeeth)
)
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_TARGET_SETTING_DIALOG)
})
ListItem() {
OpenRemindItem()
}
.listItemStyle()
.enabled(this.settingParams?.isOpen)
ListItem() {
RemindTimeItem()
}
.listItemStyle()
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_REMIND_TIME_DIALOG
)
})
// 1. 引入FrequencyItem
ListItem() {
FrequencyItem()
}
.listItemStyle()
.onClick(() => {
this.broadCast.emit(
BroadCastType.SHOW_FREQUENCY_DIALOG
)
})
}
.width(commonConst.THOUSANDTH_940)
// x. 最后实现完成按钮提交
Button() {
Text($r('app.string.complete')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
}
.width(commonConst.THOUSANDTH_800)
.height(commonConst.DEFAULT_48)
.backgroundColor($r('app.color.borderColor'))
.onClick(() => {
this.finishTaskEdit()
})
.position({
x: commonConst.THOUSANDTH_100,
y: commonConst.THOUSANDTH_800
})
CustomDialogView()
}
.width(commonConst.THOUSANDTH_1000)
}
}
实现频率任务项视图
// ets/view/TaskEditListItem.ets
import { TaskListItem } from '../model/TaskInitList'
import {
DEFAULT_12,
DEFAULT_16,
DEFAULT_20,
DEFAULT_32,
DEFAULT_56,
DEFAULT_8,
PER_DAY,
THOUSANDTH_1000,
} from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
@Extend(Text)
function targetSetCommon() {
.fontSize(DEFAULT_16)
.flexGrow(1)
.margin({ right: DEFAULT_8 })
.align(Alignment.End)
}
@Extend(Text)
function targetSettingStyle(isOpen: boolean, taskID: number) {
.fontColor(isOpen && taskID !== taskType.smile && taskID !== taskType.brushTeeth ?
$r('app.color.titleColor') :
$r('app.color.disabledColor'))
}
@Extend(Text)
function remindTimeStyle(isOpen: boolean, isAlarm: boolean) {
.fontColor(isOpen && isAlarm ? $r('app.color.titleColor') : $r('app.color.disabledColor'))
}
@Extend(Text)
function frequencyStyle(isOpen: boolean) {
.fontSize(DEFAULT_12)
.flexGrow(1)
.margin({ right: DEFAULT_8 })
.textAlign(TextAlign.End)
.fontColor(isOpen ? $r('app.color.titleColor') : $r('app.color.disabledColor'))
}
@Component
export struct TaskChooseItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text(this.settingParams.taskName).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams.isOpen })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isOpen = isOn;
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Component
export struct TargetSetItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.target_setting'))
.fontSize(DEFAULT_20)
.fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
if (this.settingParams?.unit === '') {
Text(`${this.settingParams?.targetValue}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
} else {
Text(`${this.settingParams?.targetValue} ${this.settingParams?.unit} ${PER_DAY}`)
.targetSetCommon()
.targetSettingStyle(this.settingParams?.isOpen, this.settingParams?.taskID)
}
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16);
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Component
export struct OpenRemindItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.open_reminder'))
.fontSize(DEFAULT_20)
.fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.settingParams?.isAlarm })
.width(DEFAULT_56)
.height(DEFAULT_32)
.selectedColor($r('app.color.blueColor'))
.onChange((isOn: boolean) => {
this.settingParams.isAlarm = isOn
})
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Component
export struct RemindTimeItem {
@Consume settingParams: TaskListItem
build() {
Row() {
Text($r('app.string.remind_time')).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Blank()
.layoutWeight(1)
Text(this.settingParams?.startTime)
.targetSetCommon()
.remindTimeStyle(this.settingParams.isOpen, this.settingParams.isAlarm)
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16)
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
// 1. 实现频率任务项视图
@Component
export struct FrequencyItem {
@Consume settingParams: TaskListItem
@Consume frequency: string
build() {
Row() {
Text($r('app.string.frequency')).fontSize(DEFAULT_20).fontWeight(FontWeight.Medium)
Text(this.frequency)
.targetSetCommon()
.frequencyStyle(this.settingParams.isOpen)
Image($r('app.media.right_grey')).width(DEFAULT_8).height(DEFAULT_16)
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
}
}
实现频率设置弹窗
// ets/view/TaskSettingDialog.ets
import * as commonConst from '../common/constants/CommonConstant'
import { taskType } from '../model/TaskInfo'
import { FrequencyContentType, TaskListItem } from '../model/TaskInitList'
import { createAppleRange, createDrinkRange, formatTime, returnTimeStamp } from '../viewModel/TaskTargetSetting'
import { promptAction } from '@kit.ArkUI'
import { frequencyRange } from '../viewModel/FrequencySetting'
@CustomDialog
export struct TargetSettingDialog {
controller: CustomDialogController = new CustomDialogController({
builder: TargetSettingDialog()
})
@Consume settingParams: TaskListItem
currentTime: string = commonConst.DEFAULT_TIME
currentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :
commonConst.DEFAULT_APPLE
drinkRange: string[] = createDrinkRange()
appleRange: string[] = createAppleRange()
createSubTitle() {
if (this.settingParams.taskID === taskType.getup) {
return commonConst.GET_UP_TIME_RANGE
}
if (this.settingParams.taskID === taskType.sleepEarly) {
return commonConst.SLEEP_TIME_RANGE
}
return ''
}
setTargetValue() {
if (this.settingParams.taskID === taskType.getup) {
if (!this.compareTime(commonConst.GET_UP_EARLY_TIME, commonConst.GET_UP_LATE_TIME)) {
return
}
this.settingParams.targetValue = this.currentTime
return
}
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
}
compareTime(startTime: string, endTime: string) {
if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) ||
returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {
promptAction.showToast({
message: commonConst.CHOOSE_TIME_OUT_RANGE
})
return false
}
return true
}
build() {
Column() {
Row() {
Text($r('app.string.target_setting')).fontSize(commonConst.DEFAULT_20).margin({ right: commonConst.DEFAULT_12 })
Text(this.createSubTitle())
.fontSize(commonConst.DEFAULT_16)
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.Start)
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams.taskID) > commonConst.HAS_NO_INDEX) {
TimePicker({
selected: commonConst.DEFAULT_SELECTED_TIME
})
.height(commonConst.THOUSANDTH_800)
.useMilitaryTime(true)
.onChange((value: TimePickerResult) => {
this.currentTime = formatTime(value)
})
} else {
TextPicker({ range: this.settingParams?.taskID === taskType.drinkWater ? this.drinkRange : this.appleRange,
value: this.settingParams.targetValue })
.width(commonConst.THOUSANDTH_900)
.height(commonConst.THOUSANDTH_800)
.onChange((value: string | string[]) => {
this.currentValue = (value as string)?.split(' ')[0]
})
}
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.currentTime = commonConst.DEFAULT_TIME;
this.currentValue = commonConst.DEFAULT_TEXT;
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.setTargetValue()
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_1000)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_20 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
@CustomDialog
export struct RemindTimeDialog {
controller: CustomDialogController = new CustomDialogController({
builder: RemindTimeDialog()
})
currentTime: string = commonConst.DEFAULT_TIME
@Consume settingParams: TaskListItem
build() {
Column() {
Column() {
Text($r('app.string.remind_time'))
.fontSize(commonConst.DEFAULT_20)
.margin({ top: commonConst.DEFAULT_10 })
.width(commonConst.THOUSANDTH_1000)
.textAlign(TextAlign.Start)
}
.width(commonConst.THOUSANDTH_900)
TimePicker({
selected: commonConst.DEFAULT_SELECTED_TIME
})
.height(commonConst.THOUSANDTH_800)
.useMilitaryTime(true)
.onChange((value: TimePickerResult) => {
this.currentTime = formatTime(value);
})
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.currentTime = commonConst.DEFAULT_TIME
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.settingParams.startTime = this.currentTime
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_1000)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_20 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_560)
.padding(commonConst.DEFAULT_12)
}
}
// 1.实现频率设置弹窗
@CustomDialog
export struct FrequencyDialog {
controller: CustomDialogController = new CustomDialogController({
builder: FrequencyDialog()
})
private frequencyChooseRange: FrequencyContentType[] = frequencyRange()
private currentFrequency: string = commonConst.EVERYDAY
@Consume settingParams: TaskListItem
@Consume frequency: string
setFrequency() {
const checkedArr = this.frequencyChooseRange.filter((item: FrequencyContentType) => item.isChecked)
if (checkedArr.length === this.frequencyChooseRange.length || checkedArr.length === commonConst.NO_LENGTH) {
this.currentFrequency = commonConst.EVERYDAY
this.settingParams.frequency = commonConst.INIT_WEEK_IDS
return
}
this.currentFrequency = checkedArr.reduce((sum: string, current: FrequencyContentType) => {
return sum + ' ' + current.label
}, '')
this.settingParams.frequency = checkedArr.reduce((sum: string, current: FrequencyContentType) => {
return sum === '' ? sum + current.id : sum + ',' + current.id
}, '')
}
build() {
Column() {
Column() {
Text($r('app.string.set_your_frequency'))
.fontSize(commonConst.DEFAULT_20)
.margin({ top: commonConst.DEFAULT_10 })
.width(commonConst.THOUSANDTH_1000)
.textAlign(TextAlign.Start)
}
.width(commonConst.THOUSANDTH_900)
List() {
ForEach(this.frequencyChooseRange, (item: FrequencyContentType) => {
ListItem() {
Row() {
Text(item?.label).fontSize(commonConst.DEFAULT_20)
Toggle({ type: ToggleType.Checkbox })
.onChange((isOn: boolean) => {
item.isChecked = isOn
})
}
.width(commonConst.THOUSANDTH_1000)
.justifyContent(FlexAlign.SpaceBetween)
.height(commonConst.DEFAULT_60)
}
})
}
.divider({
strokeWidth: commonConst.DEFAULT_2,
color: $r('app.color.btnBgColor')
})
.flexGrow(1)
.padding(commonConst.DEFAULT_12)
.width(commonConst.THOUSANDTH_1000)
Row() {
Text($r('app.string.cancel')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.controller.close()
})
Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor'))
.onClick(() => {
this.setFrequency()
this.frequency = this.currentFrequency
this.controller.close()
})
}
.justifyContent(FlexAlign.SpaceAround)
.width(commonConst.THOUSANDTH_900)
.height(commonConst.DEFAULT_28)
.margin({ bottom: commonConst.DEFAULT_16 })
}
.justifyContent(FlexAlign.Center)
.height(commonConst.THOUSANDTH_940)
.padding(commonConst.DEFAULT_12)
}
}
定义频率设置视图模型
// ets/viewModel/FrequencySetting.ets
import { FrequencyContentType } from "../model/TaskInitList"
export function padTo2Digits(num: number) {
return num.toString().padStart(2, '0')
}
const chineseNumOfWeek: string[] = ['一', '二', '三', '四', '五', '六', '日']
const WEEK: string = '星期'
export const frequencyRange = () => {
const frequencyRangeArr: FrequencyContentType[] = []
chineseNumOfWeek.forEach((item: string, index: number) => {
frequencyRangeArr.push({
id: (index + 1),
label: `${WEEK}${item}`,
isChecked: false
})
})
return frequencyRangeArr
}
✋ 需要参加鸿蒙认证的请点击 鸿蒙认证链接