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