介紹
將使用List組件、Toggle組件以及Router接口,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的設(shè)置頁(yè),點(diǎn)擊將跳轉(zhuǎn)到對(duì)應(yīng)的詳細(xì)設(shè)置頁(yè)面。效果圖如下:
相關(guān)概念
- [@CustomDialog]:@CustomDialog裝飾器用于裝飾自定義彈窗。
- [List]:List是常用的滾動(dòng)類容器組件之一,它按照水平或者豎直方向線性排列子組件, List的子組件必須是ListItem,它的寬度默認(rèn)充滿List的寬度。
- [TimePicker]:TimePicker是選擇時(shí)間的滑動(dòng)選擇器組件,默認(rèn)以 00:00 至 23:59 的時(shí)間區(qū)創(chuàng)建滑動(dòng)選擇器。
- [Toggle]:組件提供勾選框樣式、狀態(tài)按鈕樣式及開(kāi)關(guān)樣式。
- [Router]:通過(guò)不同的url訪問(wèn)不同的頁(yè)面,包括跳轉(zhuǎn)到應(yīng)用內(nèi)的指定頁(yè)面、用應(yīng)用內(nèi)的某個(gè)頁(yè)面替換當(dāng)前頁(yè)面、返回上一頁(yè)面或指定的頁(yè)面等。
環(huán)境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 開(kāi)發(fā)板類型:[潤(rùn)和RK3568開(kāi)發(fā)板]。
- OpenHarmony系統(tǒng):3.2 Release。
環(huán)境搭建
完成本篇Codelab我們首先要完成開(kāi)發(fā)環(huán)境的搭建,本示例以RK3568開(kāi)發(fā)板為例,參照以下步驟進(jìn)行:
- [獲取OpenHarmony系統(tǒng)版本]:標(biāo)準(zhǔn)系統(tǒng)解決方案(二進(jìn)制)。以3.2 Release版本為例:
- 搭建燒錄環(huán)境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開(kāi)發(fā)板的燒錄](méi)
- 搭建開(kāi)發(fā)環(huán)境。
- 開(kāi)始前請(qǐng)參考[工具準(zhǔn)備],完成DevEco Studio的安裝和開(kāi)發(fā)環(huán)境配置。
- 開(kāi)發(fā)環(huán)境配置完成后,請(qǐng)參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”),選擇JS或者eTS語(yǔ)言開(kāi)發(fā)。
- 工程創(chuàng)建完成后,選擇使用[真機(jī)進(jìn)行調(diào)測(cè)]。
- 鴻蒙開(kāi)發(fā)指導(dǎo)文檔:[
gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
代碼結(jié)構(gòu)解讀
本篇Codelab只對(duì)核心代碼進(jìn)行講解,完整代碼可以直接從gitee獲取。
├──entry/src/main/ets // 代碼區(qū)
│ ├──common
│ │ ├──constants
│ │ │ └──CommonConstant.ets // 常量集合文件
│ │ └──utils
│ │ ├──BroadCast.ets // 事件發(fā)布訂閱管理器
│ │ └──Log.ets // 日志打印
│ ├──entryability
│ │ └──EntryAbility.ts // 應(yīng)用入口,承載應(yīng)用的生命周期
│ ├──model
│ │ ├──EventSourceManager.ets // 事件資源管理器
│ │ ├──TaskInfo.ets // 任務(wù)信息存放
│ │ └──TaskInitList.ets // 初始化數(shù)據(jù)
│ ├──pages
│ │ ├──ListIndexPage.ets // 頁(yè)面入口
│ │ └──TaskEditPage.ets // 編輯任務(wù)頁(yè)
│ ├──view
│ │ ├──CustomDialogView.ets // 自定義彈窗統(tǒng)一入口
│ │ ├──TaskDetail.ets // 任務(wù)編輯詳情組件
│ │ ├──TaskEditListItem.ets // 任務(wù)編輯詳情Item組件
│ │ ├──TaskList.ets // 任務(wù)列表組件
│ │ └──TaskSettingDialog.ets // 彈窗組件
│ └──viewmodel
│ ├──FrequencySetting.ets // 頻率范圍設(shè)置
│ └──TaskTargetSetting.ets // 任務(wù)目標(biāo)設(shè)置
└──entry/src/main/resources
├──base
│ ├──element // 字符串以及顏色的資源文件
│ ├──media // 圖片等資源文件
│ └──profile // 頁(yè)面配置文件存放位置
├──en_US
│ └──element
│ └──string.json // 英文字符存放位置
├──rawfile // 大體積媒體資源存放位置
└──zh_CN
└──element
└──string.json // 中文字符存放位置
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
任務(wù)列表頁(yè)
任務(wù)列表頁(yè)由上部分的標(biāo)題、返回按鈕以及正中間的任務(wù)列表組成。
使用Navigation以及List組件構(gòu)成元素,使用ForEach遍歷生成具體列表。這里是Navigation構(gòu)成頁(yè)面導(dǎo)航:
// ListIndexPage.ets
Navigation() {
Column() {
// 頁(yè)面中間的列表
TaskList()
}
.width(THOUSANDTH_1000)
.justifyContent(FlexAlign.Center)
}
.size({ width:THOUSANDTH_1000, height:THOUSANDTH_1000 })
.title(ADD_TASK_TITLE)
列表右側(cè)有一個(gè)判斷是否開(kāi)啟的文字標(biāo)識(shí),點(diǎn)擊某個(gè)列表需要跳轉(zhuǎn)到對(duì)應(yīng)的任務(wù)編輯頁(yè)里。具體的列表實(shí)現(xiàn)如下:
// TaskList.ets
List({ space:commonConst.LIST_ITEM_SPACE }) {
ForEach(this.taskList, (item: TaskListItem) = > {
ListItem() {
Row() {
Row() {
Image(item?.icon)
...
Text(item?.taskName)
...
}
.width(commonConst.THOUSANDTH_500)
// 狀態(tài)顯示
if (item?.isOpen) {
Text($r('app.string.already_open'))
...
}
Image($r('app.media.right_grey'))
...
}
...
}
...
// 路由跳轉(zhuǎn)到任務(wù)編輯頁(yè)
.onClick(() = > {
router.pushUrl({
url: 'pages/TaskEditPage',
params: {
params: formatParams(item),
}
})
})
...
})
}
任務(wù)編輯頁(yè)
任務(wù)編輯頁(yè)由上方的“編輯任務(wù)”標(biāo)題以及返回按鈕,主體內(nèi)容的List配置項(xiàng)和下方的完成按鈕組成,實(shí)現(xiàn)效果如圖:
由于每一個(gè)配置項(xiàng)功能不相同,且邏輯復(fù)雜,故將其拆分為五個(gè)獨(dú)立的組件。
任務(wù)編輯頁(yè)面,由Navigation和一個(gè)自定義組件TaskDetail構(gòu)成:
// TaskEditPage.ets
Navigation() {
Column() {
TaskDetail()
}
.width(THOUSANDTH_1000)
.height(THOUSANDTH_1000)
}
.size({ width:THOUSANDTH_1000, height:THOUSANDTH_1000 })
.title(EDIT_TASK_TITLE)
.titleMode(NavigationTitleMode.Mini)
自定義組件由List以及其子組件ListItem構(gòu)成:
// TaskDetail.ets
List({ space:commonConst.LIST_ITEM_SPACE }) {
ListItem() {
TaskChooseItem()
}
...
ListItem() {
TargetSetItem()
}
...
ListItem() {
OpenRemindItem()
}
...
ListItem() {
RemindTimeItem()
}
...
ListItem() {
FrequencyItem()
}
...
}
.width(commonConst.THOUSANDTH_940)
列表的每一項(xiàng)做了禁用判斷,需要任務(wù)打開(kāi)才可以點(diǎn)擊編輯:
// TaskDetail.ets
.enabled(this.settingParams?.isOpen)
一些特殊情況的禁用,如每日微笑、每日刷牙的目標(biāo)設(shè)置不可編輯:
// TaskDetail.ets
.enabled(
this.settingParams?.isOpen
&& (this.settingParams?.taskID !== taskType.smile)
&& (this.settingParams?.taskID !== taskType.brushTeeth)
)
提醒時(shí)間在開(kāi)啟提醒打開(kāi)之后才可以編輯:
// TaskDetail.ets
.enabled(this.settingParams?.isOpen && this.settingParams?.isAlarm)
設(shè)置完成之后,點(diǎn)擊完成按鈕,此處為了模擬效果,并不與數(shù)據(jù)庫(kù)產(chǎn)生交互,因此直接彈出提示“設(shè)置完成?。。 ?。
// TaskDetail.ets
finishTaskEdit() {
prompt.showToast({
message: commonConst.SETTING_FINISHED_MESSAGE
})
}
任務(wù)編輯彈窗
彈窗由封裝的自定義組件CustomDialogView注冊(cè)事件,并在點(diǎn)擊對(duì)應(yīng)的編輯項(xiàng)時(shí)觸發(fā),從而打開(kāi)彈窗:
CustomDialogView引入實(shí)例并注冊(cè)事件:
// CustomDialogView.ets
targetSettingDialog = new CustomDialogController({
builder: TargetSettingDialog(),
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx:ZERO, dy:MINUS_20 }
})
...
// 注冊(cè)事件
this.broadCast.on(
BroadCastType.SHOW_FREQUENCY_DIALOG,
() = > {
this.FrequencyDialogController.open();
})
點(diǎn)擊對(duì)應(yīng)的編輯項(xiàng)觸發(fā):
// TaskDetail.ets
.onClick(() = > {
if (this.broadCast !== undefined) {
this.broadCast.emit(
BroadCastType.SHOW_TARGET_SETTING_DIALOG);
}
})
自定義彈窗的實(shí)現(xiàn):
因?yàn)槿蝿?wù)目標(biāo)設(shè)置有三種類型:
- 早睡早起的時(shí)間
- 喝水的量度
- 吃蘋果的個(gè)數(shù)
如下圖所示:
故根據(jù)任務(wù)的ID進(jìn)行區(qū)分,將同一彈窗復(fù)用:
// TaskSettingDialog.ets
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams?.taskID) > commonConst.HAS_NO_INDEX) {
TimePicker({
selected:commonConst.DEFAULT_SELECTED_TIME
})
...
} else {
TextPicker({ range:this.settingParams?.taskID === taskType.drinkWater ? this.drinkRange : this.appleRange,
value: this.settingParams.targetValue})
...
}
彈窗確認(rèn)的時(shí)候?qū)⑿薷暮玫闹蒂x予該項(xiàng)設(shè)置,如不符合規(guī)則,將彈出提示:
// TaskSettingDialog.ets
// 校驗(yàn)規(guī)則
compareTime(startTime: string, endTime: string) {
if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) ||
returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {
// 彈出提示
prompt.showToast({
message:commonConst.CHOOSE_TIME_OUT_RANGE
})
return false;
}
return true;
}
// 設(shè)置修改項(xiàng)
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;
其余彈窗實(shí)現(xiàn)基本類似,這里不再贅述。
審核編輯 黃宇
-
組件
+關(guān)注
關(guān)注
1文章
503瀏覽量
17786 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1966瀏覽量
29962 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3641瀏覽量
16061
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論