鸿蒙任务项设置案例实战
目录
案例效果
资源文件与初始化
string.json
color.json
CommonConstant
添加任务
首页组件
任务列表初始化
任务列表视图
任务编辑页
添加跳转
任务目标设置模型(formatParams)
编辑页面
详情页
任务编辑列表项
目标设置展示
引入目标设置
目标设置展示实现
TaskInfo 枚举模型设置
弹窗构造逻辑
定义单击事件
定义 BroadCast
定义弹窗视图
定义弹窗 builder 组件
目标设置弹窗实现
目标设置窗口逻辑
任务目标设置视图模型
频率设置视图模型
时间提醒弹窗实现
更新TaskDetail
实现编辑任务列表的开启提醒与提醒时间
实现时间提醒弹窗
频率弹窗和提交完成的实现
实现频率任务项视图
实现频率设置弹窗
定义频率设置视图模型
案例效果
资源文件与初始化
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.etsexport 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 = 60export const LIST_ITEM_SPACE: number = 2export 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 = -1export 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.etsimport 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[] = TaskInitListbuild() {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.etsexport interface TaskListItem {taskID: numbertaskName: ResourceisOpen: booleanunit: stringicon: ResourcetargetValue: stringisAlarm: booleanstartTime: stringfrequency: 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.etsimport * 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.etsimport * 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/TaskTargetSettingimport { TaskListItem } from '../model/TaskInitList'
export const formatParams = (params: TaskListItem) => {return JSON.stringify(params)
}
编辑页面
// ets/pages/TaskEditPage.etsimport { 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.etsimport * 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.etsimport { TaskListItem } from '../model/TaskInitList'
import {DEFAULT_20,DEFAULT_32,DEFAULT_56,THOUSANDTH_1000,
} from '../common/constants/CommonConstant'@Component
export struct TaskChooseItem {@Consume settingParams: TaskListItembuild() {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.etsimport * as commonConst from '../common/constants/CommonConstant'
import { TaskListItem } from '../model/TaskInitList'
import {TaskChooseItem,// 2. 引入TargetSetItemTargetSetItem
} 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.etsimport { 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: TaskListItembuild() {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.etsexport 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.etsexport 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 = thisif (!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.etsimport { 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: BroadCasttargetSettingDialogController: 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 = thisthis.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.etsimport * 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.etsimport * 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: TaskListItemcurrentTime: string = commonConst.DEFAULT_TIMEcurrentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :commonConst.DEFAULT_APPLEdrinkRange: 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.currentTimereturn}if (this.settingParams.taskID === taskType.sleepEarly) {if (!this.compareTime(commonConst.SLEEP_EARLY_TIME, commonConst.SLEEP_LATE_TIME)) {return}this.settingParams.targetValue = this.currentTimereturn}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_TIMEthis.currentValue = commonConst.DEFAULT_TEXTthis.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.etsimport { 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 = 0let minute: number = 0if (value.hour !== undefined && value.minute !== undefined) {hour = value.hourminute = 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.etsexport function padTo2Digits(num: number) {return num.toString().padStart(2, '0')
}
时间提醒弹窗实现
更新TaskDetail
// ets/view/TaskDetail.etsimport * 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: TaskListItembuild() {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: TaskListItembuild() {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: TaskListItembuild() {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: TaskListItembuild() {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: TaskListItemcurrentTime: string = commonConst.DEFAULT_TIMEcurrentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :commonConst.DEFAULT_APPLEdrinkRange: 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.currentTimereturn}if (this.settingParams?.taskID === taskType.sleepEarly) {if (!this.compareTime(commonConst.SLEEP_EARLY_TIME, commonConst.SLEEP_LATE_TIME)) {return}this.settingParams.targetValue = this.currentTimereturn}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: TaskListItembuild() {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_TIMEthis.controller.close()})Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor')).onClick(() => {this.settingParams.startTime = this.currentTimethis.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.etsimport * 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.EVERYDAYparseRouterParams() {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. 引入FrequencyItemListItem() {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.etsimport { 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: TaskListItembuild() {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: TaskListItembuild() {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: TaskListItembuild() {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: TaskListItembuild() {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: stringbuild() {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.etsimport * 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: TaskListItemcurrentTime: string = commonConst.DEFAULT_TIMEcurrentValue: string = this.settingParams.taskID === taskType.drinkWater ? commonConst.DEFAULT_TEXT :commonConst.DEFAULT_APPLEdrinkRange: 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.currentTimereturn}if (this.settingParams?.taskID === taskType.sleepEarly) {if (!this.compareTime(commonConst.SLEEP_EARLY_TIME, commonConst.SLEEP_LATE_TIME)) {return}this.settingParams.targetValue = this.currentTimereturn}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: TaskListItembuild() {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_TIMEthis.controller.close()})Text($r('app.string.confirm')).fontSize(commonConst.DEFAULT_20).fontColor($r('app.color.blueColor')).onClick(() => {this.settingParams.startTime = this.currentTimethis.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: stringsetFrequency() {const checkedArr = this.frequencyChooseRange.filter((item: FrequencyContentType) => item.isChecked)if (checkedArr.length === this.frequencyChooseRange.length || checkedArr.length === commonConst.NO_LENGTH) {this.currentFrequency = commonConst.EVERYDAYthis.settingParams.frequency = commonConst.INIT_WEEK_IDSreturn}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.currentFrequencythis.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.etsimport { 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
}
基础知识:切换按钮 (Toggle)
Toggle组件提供状态按钮样式、勾选框样式和开关样式,一般用于两种状态之间的切换。
创建切换按钮
Toggle通过调用接口来创建,接口调用形式如下:
Toggle(options: { type: ToggleType, isOn?: boolean })
其中,ToggleType为开关类型,包括Button、Checkbox和Switch,isOn为切换按钮的状态。
API version 11开始,Checkbox默认样式由圆角方形变为圆形。
接口调用有以下两种形式:
- 创建不包含子组件的Toggle。
当ToggleType为Checkbox或者Switch时,用于创建不包含子组件的Toggle:
Toggle({ type: ToggleType.Checkbox, isOn: false })
Toggle({ type: ToggleType.Checkbox, isOn: true })
Toggle({ type: ToggleType.Switch, isOn: false })
Toggle({ type: ToggleType.Switch, isOn: true })
- 创建包含子组件的Toggle。
当ToggleType为Button时,只能包含一个子组件,如果子组件有文本设置,则相应的文本内容会显示在按钮上。
Toggle({ type: ToggleType.Button, isOn: false }) {Text('status button').fontColor('#182431').fontSize(12)
}.width(100)
Toggle({ type: ToggleType.Button, isOn: true }) {Text('status button').fontColor('#182431').fontSize(12)
}.width(100)
自定义样式
- 通过selectedColor属性设置Toggle打开选中后的背景颜色。
Toggle({ type: ToggleType.Button, isOn: true }) {Text('status button').fontColor('#182431').fontSize(12)
}.width(100).selectedColor(Color.Pink)
Toggle({ type: ToggleType.Checkbox, isOn: true }).selectedColor(Color.Pink)
Toggle({ type: ToggleType.Switch, isOn: true }).selectedColor(Color.Pink)
- 通过switchPointColor属性设置Switch类型的圆形滑块颜色,仅对type为ToggleType.Switch生效。
Toggle({ type: ToggleType.Switch, isOn: false }).switchPointColor(Color.Pink)
Toggle({ type: ToggleType.Switch, isOn: true }).switchPointColor(Color.Pink)
添加事件
除支持通用事件外,Toggle还用于选中和取消选中后触发某些操作,可以绑定onChange事件来响应操作后的自定义行为。
Toggle({ type: ToggleType.Switch, isOn: false }).onChange((isOn: boolean) => {if(isOn) {// 需要执行的操作}})
案例整理
// ets/pages/toggle/usagePage.ets@Entry
@Component
struct usagePage {@State isOn: boolean = truebuild() {Column({ space: 20 }) {Row() {Toggle({ type: ToggleType.Checkbox, isOn: false })Toggle({ type: ToggleType.Checkbox, isOn: true })}Row() {Toggle({ type: ToggleType.Switch, isOn: false })Toggle({ type: ToggleType.Switch, isOn: true })}Row() {Toggle({ type: ToggleType.Button, isOn: false }) {Text('status button').fontColor('#182431').fontSize(12)}.width(100)Toggle({ type: ToggleType.Button, isOn: true }) {Text('status button').fontColor('#182431').fontSize(12)}.width(100)}Row() {Toggle({ type: ToggleType.Button, isOn: true }) {Text('status button').fontColor('#182431').fontSize(12)}.width(100).selectedColor(Color.Orange)Toggle({ type: ToggleType.Checkbox, isOn: true }).selectedColor(Color.Orange)Toggle({ type: ToggleType.Switch, isOn: true }).selectedColor(Color.Orange)}Row() {Toggle({ type: ToggleType.Switch, isOn: false }).switchPointColor(Color.Orange)Toggle({ type: ToggleType.Switch, isOn: true }).switchPointColor(Color.Orange)}Row() {Toggle({ type: ToggleType.Switch, isOn: this.isOn }).onChange((isOn: boolean) => {this.isOn = !this.isOn})Text(`${this.isOn}`)}}.width('100%')}
}
场景示例
Toggle用于切换蓝牙开关状态。
// ets/pages/toggle/CasePage.etsimport { promptAction } from '@kit.ArkUI';@Entry
@Component
struct CasePage {@State BOnSt: promptAction.ShowToastOptions = { 'message': 'Bluetooth is on.' }@State BOffSt: promptAction.ShowToastOptions = { 'message': 'Bluetooth is off.' }build() {Column() {Row() {Text("Bluetooth Mode").height(50).fontSize(16)}Row() {Text("Bluetooth").height(50).padding({ left: 10 }).fontSize(16).textAlign(TextAlign.Start).backgroundColor(0xFFFFFF)Toggle({ type: ToggleType.Switch }).margin({ left: 200, right: 10 }).onChange((isOn: boolean) => {if (isOn) {promptAction.showToast(this.BOnSt)} else {promptAction.showToast(this.BOffSt)}})}.backgroundColor(0xFFFFFF)}.padding(10).backgroundColor(0xDCDCDC).width('100%').height('100%')}
}
基础知识:学习Picker选择器
CalendarPicker
示例
// ets/pages/picker/CalendarPickerPage.ets@Entry
@Component
struct CalendarPickerPage {private selectedDate: Date = new Date('2025-03-05')build() {Column() {Text('月历日期选择器').fontSize(30)Column() {CalendarPicker({ hintRadius: 10, selected: this.selectedDate }).edgeAlign(CalendarAlign.END).textStyle({ color: "#182431", font: { size: 20, weight: FontWeight.Normal } }).margin(10).onChange((value) => {console.info("CalendarPicker onChange:" + JSON.stringify(value))})}.alignItems(HorizontalAlign.End).width("100%")}.width('100%')}
}
DatePicker
示例
// ets/pages/picker/DatePickerPage.ets@Entry
@Component
struct DatePickerPage {@State isLunar: boolean = falseprivate selectedDate: Date = new Date('2025-08-08')build() {Column() {Button('切换公历农历').margin({ top: 30, bottom: 30 }).onClick(() => {this.isLunar = !this.isLunar})DatePicker({start: new Date('1970-1-1'),end: new Date('2100-1-1'),selected: this.selectedDate}).disappearTextStyle({ color: Color.Gray, font: { size: '16fp', weight: FontWeight.Bold } }).textStyle({ color: '#182431', font: { size: '18fp', weight: FontWeight.Normal } }).selectedTextStyle({ color: '#0000FF', font: { size: '26fp', weight: FontWeight.Regular } }).lunar(this.isLunar).onDateChange((value: Date) => {this.selectedDate = valueconsole.info('select current date is: ' + value.toString())})}.width('100%')}
}
TextPicker
示例1(设置选择器列数)
该示例通过配置range实现单列或多列文本选择器。
// ets/pages/picker/TextPicker01Page.etsclass bottom {bottom: number = 50
}let bott: bottom = new bottom()@Entry
@Component
struct TextPicker01Page {private select: number = 1private apFruits: string[] = ['apple1', 'apple2', 'apple3', 'apple4']private orFruits: string[] = ['orange1', 'orange2', 'orange3', 'orange4']private peFruits: string[] = ['peach1', 'peach2', 'peach3', 'peach4']private multi: string[][] = [this.apFruits, this.orFruits, this.peFruits]private cascade: TextCascadePickerRangeContent[] = [{text: '辽宁省',children: [{ text: '沈阳市', children: [{ text: '沈河区' }, { text: '和平区' }, { text: '浑南区' }] },{ text: '大连市', children: [{ text: '中山区' }, { text: '金州区' }, { text: '长海县' }] }]},{text: '吉林省',children: [{ text: '长春市', children: [{ text: '南关区' }, { text: '宽城区' }, { text: '朝阳区' }] },{ text: '四平市', children: [{ text: '铁西区' }, { text: '铁东区' }, { text: '梨树县' }] }]},{text: '黑龙江省',children: [{ text: '哈尔滨市', children: [{ text: '道里区' }, { text: '道外区' }, { text: '南岗区' }] },{ text: '牡丹江市', children: [{ text: '东安区' }, { text: '西安区' }, { text: '爱民区' }] }]}]build() {Column() {TextPicker({ range: this.apFruits, selected: this.select }).onChange((value: string | string[], index: number | number[]) => {console.info('Picker item changed, value: ' + value + ', index: ' + index)}).margin(bott)TextPicker({ range: this.multi }).onChange((value: string | string[], index: number | number[]) => {console.info('TextPicker 多列:onChange ' + JSON.stringify(value) + ', ' + 'index: ' + JSON.stringify(index))}).margin(bott)TextPicker({ range: this.cascade }).onChange((value: string | string[], index: number | number[]) => {console.info('TextPicker 多列联动:onChange ' + JSON.stringify(value) + ', ' + 'index: ' +JSON.stringify(index))})}}
}
示例2(设置文本样式)
该示例通过配置disappearTextStyle、textStyle、selectedTextStyle实现文本选择器中的文本样式。
// ets/pages/picker/TextPicker02Page.ets@Entry
@Component
struct TextPicker02Page {private select: number = 1private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4']build() {Column() {TextPicker({ range: this.fruits, selected: this.select }).onChange((value: string | string[], index: number | number[]) => {console.info('Picker item changed, value: ' + value + ', index: ' + index)}).disappearTextStyle({ color: Color.Red, font: { size: 15, weight: FontWeight.Lighter } }).textStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Normal } }).selectedTextStyle({ color: Color.Blue, font: { size: 30, weight: FontWeight.Bolder } })}.width('100%').height('100%')}
}
示例3(设置无分割线样式)
该示例通过配置divider为null实现无分割线样式的文本选择器。
// ets/pages/picker/TextPicker03Page.ets@Entry
@Component
struct TextPicker03Page {private select: number = 1private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4']build() {Column() {TextPicker({ range: this.fruits, selected: this.select }).onChange((value: string | string[], index: number | number[]) => {console.info('Picker item changed, value: ' + value + ', index: ' + index)}).disappearTextStyle({color: Color.Red, font: {size: 15, weight: FontWeight.Lighter}}).textStyle({color: Color.Black, font: {size: 20, weight: FontWeight.Normal}}).selectedTextStyle({color: Color.Blue, font: {size: 30, weight: FontWeight.Bolder}}).divider(null)}.width('100%').height('100%')}
}
示例4(设置分割线样式)
该示例通过配置divider的DividerOptions类型实现分割线样式的文本选择器。
// ets/pages/picker/TextPicker04Page.ets@Entry
@Component
struct TextPicker04Page {private select: number = 1private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4']build() {Column() {TextPicker({ range: this.fruits, selected: this.select }).onChange((value: string | string[], index: number | number[]) => {console.info('Picker item changed, value: ' + value + ', index: ' + index)}).disappearTextStyle({ color: Color.Red, font: { size: 15, weight: FontWeight.Lighter } }).textStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Normal } }).selectedTextStyle({ color: Color.Blue, font: { size: 30, weight: FontWeight.Bolder } }).divider({strokeWidth: 10,color: Color.Red,startMargin: 10,endMargin: 20} as DividerOptions)}.width('100%').height('100%')}
}
示例5(设置渐隐效果)
该示例通过gradientHeight自定义TextPicker的渐隐效果高度。
// ets/pages/picker/TextPicker05Page.ets@Entry
@Component
struct TextPicker05Page {private select: number = 1private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4']build() {Column() {TextPicker({ range: this.fruits, selected: this.select }).onChange((value: string | string[], index: number | number[]) => {console.info('Picker item changed, value: ' + value + ', index: ' + index)}).disappearTextStyle({ color: Color.Red, font: { size: 15, weight: FontWeight.Lighter } }).textStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Normal } }).selectedTextStyle({ color: Color.Blue, font: { size: 30, weight: FontWeight.Bolder } }).gradientHeight(100)}.width('100%').height('100%')}
}
TimePicker
示例
// ets/pages/picker/TimePicker.ets@Entry
@Component
struct TimePickerExample {@State isMilitaryTime: boolean = falseprivate selectedTime: Date = new Date('2025-07-22T08:00:00')build() {Column() {Button('切换12小时制/24小时制').margin(30).onClick(() => {this.isMilitaryTime = !this.isMilitaryTime})TimePicker({selected: this.selectedTime,format: TimePickerFormat.HOUR_MINUTE_SECOND}).useMilitaryTime(this.isMilitaryTime).onChange((value: TimePickerResult) => {if(value.hour >= 0) {this.selectedTime.setHours(value.hour, value.minute)console.info(`${value}`)}}).disappearTextStyle({color: Color.Red, font: {size: 15, weight: FontWeight.Lighter}}).textStyle({color: Color.Black, font: {size: 20, weight: FontWeight.Normal}}).selectedTextStyle({color: Color.Blue, font: {size: 30, weight: FontWeight.Bolder}})}.width('100%')}
}
相关文章:

鸿蒙任务项设置案例实战
目录 案例效果 资源文件与初始化 string.json color.json CommonConstant 添加任务 首页组件 任务列表初始化 任务列表视图 任务编辑页 添加跳转 任务目标设置模型(formatParams) 编辑页面 详情页 任务编辑列表项 目标设置展示 引入目标…...

TDengine 的 AI 应用实战——运维异常检测
作者: derekchen Demo数据集准备 我们使用公开的 NAB数据集 里亚马逊 AWS 东海岸数据中心一次 API 网关故障中,某个服务器上的 CPU 使用率数据。数据的频率为 5min,单位为占用率。由于 API 网关的故障,会导致服务器上的相关应用…...
DHCP与DNS的配置
在网络管理中,DHCP(动态主机配置协议)和DNS(域名系统)是两个关键组件。DHCP用于自动分配IP地址,而DNS用于将域名解析为IP地址。本文将详细介绍如何在Linux环境下配置DHCP和DNS服务。 一、DHCP配置 1. 安装…...

使用Plop.js高效生成模板文件
前情 开发是个创造型的职业,也是枯燥的职业,因为开发绝大多数都是每天在业务的代码中无法自拨,说到开发工作,就永远都逃不开新建文件的步骤,特别现在组件化开发胜行,每天都是在新建新建组件的道路上一去不…...

Vue框架2(vue搭建方式2:利用脚手架,ElementUI)
一.引入vue第二种搭建方式 在以前的前端项目中,一个项目需要多个html文件实现页面之前的切换,如果页面中需要依赖js或者css文件,那么我们就需要在多个html文件中都需要导入vue.js文件,太过繁琐. 现在前端开发都采用单页面结果,一个项目中只有一个html文件 其他不同的内容都写…...

mac 设置cursor (像PyCharm一样展示效果)
一、注册 Cursor - The AI Code Editor 二、配置Python环境 我之前使用pycharm创建的python项目,以及创建了虚拟环境,现在要使用cursor继续开发。 2.1 选择Python 虚拟环境 PyCharm 通常将虚拟环境存储在项目目录下的 venv 或 .venv 文件夹中…...

SpringCloudAlibaba微服务架构
技术架构图 SpringCloudAlibaba微服务架构 说明: 1.1、采用SpringCloudAlibaba分布式微服务架构,使用Nginx做代理,服务治理使用Nacos组件,Gateway网关做权限验证、路由、过滤。 1.2、Redis做消息缓存,包括数据大屏、数…...

Java高级 | 【实验三】Springboot 静态资源访问
隶属文章: Java高级 | (二十二)Java常用类库-CSDN博客 系列文章: Java高级 | 【实验一】Spring Boot安装及测试 最新-CSDN博客 Java高级 | 【实验二】Springboot 控制器类相关注解知识-CSDN博客 目录 一、Thymeleaf 1.1 是什么&…...
C语言_预处理详解
1. 预定义符号 C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的 1 __FILE__ //进行编译的源文件 2 __LINE__//文件当前的行号 3 __DATE__ //文件被编译的日期 4 __TIME__//文件被编译的时间 5 __STDC__//如果编译器遵循ANSI…...
将前后端分离版的前端vue打包成EXE的完整解决方案
将若依前后端分离版的前端打包成EXE的完整解决方案 将若依前后端分离版的Vue前端打包成Windows可执行文件(.exe),同时保持与后端API的通信,需要使用Electron框架来实现。下面是详细的步骤和解决方案。 一、准备工作 1. 环境要求 Node.js (推荐v16+)npm 或 yarn若依前后端分…...
物联网协议之MQTT(一)基础概念和设备
前言: 本文内容均以实战出发,像MQTT概念这种基础内容建议大家自行百度。 推荐资料: mica-mqtt文档 一、MQTT简单介绍 作为当今物联网的主流协议,MQTT的使用范围非常广,如果你想了解甚至是从事物联网行业,…...

「Java教案」Java程序的构成
课程目标 1.知识目标 能够按照Java标识符的命名规则,规范变量的命名。能够区分Java中的关键字与保留字。能够对注释进行分类,根据注释的用途合理的选择注释方式。 2.能力目标 能编写符合规范的标识符。能识别Java中的关键字和…...
还原Windows防火墙
还原Windows防火墙 1. 背景2. 为何“还原”完胜“关闭”?三大核心优势3. 还原防火墙默认值操作步骤4. 还原防火墙时,系统背后的工作5. 需要还原防火墙场景一招拯救混乱网络!还原Windows防火墙,找回你的“安全速度”1. 背景 你是否曾因一时误操作关闭了Windows防火墙?是…...

区块链可投会议CCF B--EDBT 2026 截止10.8 附录用率
Conference:EDBT: 29th International Conference on Extending Database Technology CCF level:CCF B Categories:数据库/数据挖掘/内容检索 Year:2026 Conference time:24th March - 27th…...

经典ReLU回归!重大缺陷「死亡ReLU问题」已被解决
来源 | 机器之心 在深度学习领域中,对激活函数的探讨已成为一个独立的研究方向。例如 GELU、SELU 和 SiLU 等函数凭借其平滑梯度与卓越的收敛特性,已成为热门选择。 尽管这一趋势盛行,经典 ReLU 函数仍因其简洁性、固有稀疏性及…...

在VSCode中开发一个uni-app项目
创建项目 使用命令行工具(例如 vue-cli)来创建一个新的 uni-app 项目。 创建以JavaScript开发的工程 npx degit dcloudio/uni-preset-vue#vite my-vue3-project //或者 npx degit dcloudio/uni-preset-vue#vite-alpha my-vue3-project创建以TypeScript…...
quic为什么没有被大规模应用?
一、成本 将应用程序从 HTTP/2 迁移到 HTTP/3,或从 TCP 迁移到 UDP 需要付出一定的努力。它需要将整个应用层实现和传输层实现转换到UDP,并在服务器端和客户端构建一个全新的解决方案。对于资源有限的小型流媒体供应商来说,这是一个不小的挑…...
Delft3D软件介绍及建模原理和步骤;Delft3D数值模拟溶质运移模型建立;地表水环境影响评价报告编写思路
📚 教程以地表水数值模拟软件 Delft3D 4.03.00 的操作为核心内容,系统涵盖地表水水动力建模、基础资料获取、边界条件设定、模型率定与验证以及数据分析处理等关键环节。通过全面讲解,学员将掌握地表水数值模拟的全过程实际操作技术。 &…...
书籍在其他数都出现k次的数组中找到只出现一次的数(7)0603
题目 给定一个整型数组arr和一个大于1的整数k。已知arr中只有1个数出现了1次,其他的数都出现了k次,请返回只出现了1次的数。 解答: 对此题进行思路转换,可以将此题,转换成k进制数。 k进制的两个数c和d,…...
开源模型应用落地-OpenAI Agents SDK-集成Qwen3-8B-function_tool(二)
一、前言 在人工智能技术迅猛发展的今天,OpenAI Agents SDK 为开发者提供了一个强大的工具集,用于构建基于 Python 的智能代理应用。这些代理可以执行从简单任务到复杂决策的一系列操作,极大地提升了应用程序的智能化水平。 通过 OpenAI Agents SDK,可以利用 Python 编程语…...

Python - 爬虫;Scrapy框架之插件Extensions(四)
阅读本文前先参考 https://blog.csdn.net/MinggeQingchun/article/details/145904572 在 Scrapy 中,扩展(Extensions)是一种插件,允许你添加额外的功能到你的爬虫项目中。这些扩展可以在项目的不同阶段执行,比如启动…...

Spark实战能力测评模拟题精析【模拟考】
1.println(Array(1,2,3,4,5).filter(_%20).toList() 输出结果是(B) A. 2 4 B. List(2,4) C. List(1,3,5) D. 1 3 5 2.println(Array("tom","team","pom") .filter(_.matches("")).toList) 输出结果为(List(tom,…...

【OSG学习笔记】Day 15: 路径动画与相机漫游
本章来学习下漫游相机。 路径动画与相机漫游 本届内容比较简单,其实就是实现物体的运动和相机的运动 当然这两个要一起执行。 贝塞尔曲线 贝塞尔曲线(Bzier curve)是一种在计算机图形学、动画制作、工业设计等领域广泛应用的参数曲线&am…...

PostgreSQL(PostGIS)触发器+坐标转换案例
需求,只录入一份坐标参考为4326的数据,但是发布的数据要求坐标必须是3857 对这种需求可以利用数据库触发器实现数据的同步 步骤: 1. 使用ArcGIS Pro创建一个名字为testfc_4326的图层,坐标参考为4326 2. 使用Pro再创建一个名字…...

Constraints and Triggers
目录 Kinds of Constraints Single-Attribute Keys Multiattribute Key Foreign Keys Expressing Foreign Keys Enforcing Foreign-Key Constraints Actions Taken Attribute-Based Checks Timing of Checks Tuple-Based Checks Assertions Timing of Assertion Ch…...
基于windows系统的netcore架构与SqlServer数据库,实现双机热备。
以下是基于 SQL Server Always On 可用性组 和 故障转移群集 的详细配置步骤,用于实现双机热备。 步骤 1:准备环境 1.1 硬件和软件准备 两台服务器:分别作为主服务器和备用服务器。SQL Server版本:确保两台服务器上安装的SQL S…...
【转bin】EXCEL数据转bin
如果DEC2BIN函数的默认设置无法满足需求(它最多只能处理10位的二进制转换),可以通过VBA宏方法来处理较大数的二进制转换并提取特定位置的数字: 十进制转二进制(不限位宽) 1、打开VBA编辑器(Al…...

BERT:让AI真正“读懂”语言的革命
BERT:让AI真正“读懂”语言的革命 ——图解谷歌神作《BERT: Pre-training of Deep Bidirectional Transformers》 2018年,谷歌AI团队扔出一篇核弹级论文,引爆了整个NLP领域。这个叫BERT的模型在11项任务中屠榜,甚至超越人类表现…...
【计算机组成原理】SPOOLing技术
SPOOLing技术 关键点内容核心思想通过输入/输出井虚拟化独占设备,实现共享,即让多个作业共享一台独占设备依赖条件1. 外存(井文件)2. 多道程序设计虚拟实现多道程序技术磁盘缓冲数据流方向输入设备 → 输入井 → CPU → 输出井 →…...

冷雨泉教授团队:新型视觉驱动智能假肢手,拟人化抓握技术突破,助力截肢者重获生活自信
研究背景:日常生活中,健康人依靠手完成对物体的操作。对于手部截肢患者,手部的缺失导致他们难以有效地操作物体,进而影响正常的日常生活。拥有一个能够实现拟人地自然抓取多种日常物体的五指动力假手是手部截肢患者的夙愿…...