大家好,我是潘Sir,持續分享IT技術,幫你少走彎路。《鴻蒙應用開發從入門到項目實戰》系列文章持續更新中,陸續更新AI+編程、企業級項目實戰等原創內容、歡迎關注!
一、HarmonyOS應用開發相關概念
在具體開發鴻蒙應用之前,需要先了解有關HarmonyOS應用的一些基本概念:UI框架的簡單説明、應用模型的基本概念。
1.1 UI框架
HarmonyOS提供了一套UI開發框架,即方舟開發框架(ArkUI框架)。方舟開發框架可為開發者提供應用UI開發所必需的能力,比如多種組件、佈局計算、動畫能力、UI交互、繪製等。
方舟開發框架針對不同目的和技術背景的開發者提供了兩種開發範式,分別是基於ArkTS的聲明式開發範式(簡稱“聲明式開發範式”)和兼容JS的類Web開發範式(簡稱“類Web開發範式”)。以下是兩種開發範式的簡單對比。
| 開發範式名稱 | 語言生態 | UI更新方式 | 適用場景 | 適用人羣 |
|---|---|---|---|---|
| 聲明式開發範式 | ArkTS語言 | 數據驅動更新 | 複雜度較大、團隊合作度較高的程序 | 移動系統應用開發人員、系統應用開發人員 |
| 類Web開發範式 | JS語言 | 數據驅動更新 | 界面較為簡單的程序應用和卡片 | Web前端開發人 |
1.2 應用模型
應用模型是HarmonyOS為開發者提供的應用程序所需能力的抽象提煉,它提供了應用程序必備的組件和運行機制。有了應用模型,開發者可以基於一套統一的模型進行應用開發,使應用開發更簡單、高效。
隨着系統的演進發展,HarmonyOS先後提供了兩種應用模型:
- FA(Feature Ability)模型: HarmonyOS API 7開始支持的模型,已經不再主推。
-
Stage模型: HarmonyOS API 9開始新增的模型,是目前主推且會長期演進的模型。在該模型中,由於提供了AbilityStage、WindowStage等類作為應用組件和Window窗口的“舞台”,因此稱這種應用模型為Stage模型。
瞭解鴻蒙應用開發相關概念後,接下來進入UI的開發。
二、UI開發概述
方舟開發框架(簡稱ArkUI)為HarmonyOS應用的UI開發提供了完整的基礎設施,包括簡潔的UI語法、豐富的UI功能(組件、佈局、動畫以及交互事件),以及實時界面預覽工具等,可以支持開發者進行可視化界面開發。
1.1 基本概念
UI:
即用户界面。開發者可以將應用的用户界面設計為多個功能頁面,每個頁面進行單獨的文件管理,並通過頁面路由API完成頁面間的調度管理如跳轉、回退等操作,以實現應用內的功能解耦。
組件:
UI構建與顯示的最小單位,如列表、網格、按鈕、單選框、進度條、文本等。開發者通過多種組件的組合,構建出滿足自身應用訴求的完整界面。
1.2 兩種開發範式
針對不同的應用場景及技術背景,方舟開發框架提供了兩種開發範式,分別是:基於ArkTS的聲明式開發範式(檢簡稱”聲明式開發範式“)和兼容JS的類Web開發範式(簡稱”類Web開發範式“ )。
-
聲明式開發範式:
採用基於TypeScript聲明式UI語法擴展而來的ArkTS語言,從組件、動畫和狀態管理三個維度提供UI繪製能力。
-
類Web開發範式:
採用經典的HML、CSS、JavaScript三段式開發方式,即使用HML標籤文件搭建佈局、使用CSS文件描述樣式、使用JavaScript文件處理邏輯。該範式更符合於Web前端開發者的使用習慣,便於快速將已有的Web應用改造成方舟開發框架應用。
在開發一款新應用時,推薦採用聲明式開發範式來構建UI,主要基於以下幾點考慮:
- 開發效率:聲明式開發範式更接近自然語義的編程方式,開發者可以直觀地描述UI,無需關心如何實現UI繪製和渲染,開發高效簡潔。
-
應用性能:如下圖方舟開發框架示意圖所示,兩種開發範式的UI後端引擎和語言運行時是共用的,但是相比類Web開發範式,聲明式開發範式無需JS框架進行頁面DOM管理,渲染更新鏈路更為精簡,佔用內存更少,應用性能更佳。
<center>圖 方舟開發框架示意圖</center>
- 發展趨勢:聲明式開發範式後續會作為主推的開發範式持續演進,為開發者提供更豐富、更強大的能力。
1.3 不同應用類型支持的開發範式
根據所選用HarmonyOS應用模型(Stage模型、FA模型)和頁面形態(應用或服務的普通頁面、卡片)的不同,對應支持的UI開發範式也有所差異,詳見下表。
<center>表 支持的UI開發範式</center>
| 應用模型 | 頁面形態 | 支持的UI開發範式 |
|---|---|---|
| Stage模型(推薦) | 應用或服務的頁面 | 聲明式開發範式(推薦) |
| 卡片 | 聲明式開發範式(推薦)類Web開發範式 | |
| FA模型 | 應用或服務的頁面 | 聲明式開發範式類Web開發範式 |
| 卡片 | 類Web開發範式 |
三、基於ArkTS的聲明式開發範式
基於ArkTS的聲明式開發範式的方舟開發框架是一套開發極簡、高性能、支持跨設備的UI開發框架,提供了構建HarmonyOS應用UI所必需的能力,主要包括:
- ArkTS
ArkTS是HarmonyOS優選的主力應用開發語言,圍繞應用開發在TypeScript(簡稱TS)生態基礎上做了進一步擴展。擴展能力包含聲明式UI描述、自定義組件、動態擴展UI元素、狀態管理和渲染控制。狀態管理作為基於ArkTS的聲明式開發範式的特色,通過功能不同的裝飾器給開發者提供了清晰的頁面更新渲染流程和管道。狀態管理包括UI組件狀態和應用程序狀態,兩者協作可以使開發者完整地構建整個應用的數據更新和UI渲染。 -
佈局
佈局是UI的必要元素,它定義了組件在界面中的位置。ArkUI框架提供了多種佈局方式,除了基礎的線性佈局、層疊佈局、彈性佈局、相對佈局、柵格佈局外,也提供了相對複雜的列表、宮格、輪播。
-
組件
組件是UI的必要元素,形成了在界面中的樣子,由框架直接提供的稱為系統組件,由開發者定義的稱為自定義組件。系統內置組件包括按鈕、單選框、進度條、文本等。開發者可以通過鏈式調用的方式設置系統內置組件的渲染效果。開發者可以將系統內置組件組合為自定義組件,通過這種方式將頁面組件化為一個個獨立的UI單元,實現頁面不同單元的獨立創建、開發和複用,具有更強的工程性。
-
頁面路由和組件導航
應用可能包含多個頁面,可通過頁面路由實現頁面間的跳轉。一個頁面內可能存在組件間的導航如典型的分欄,可通過導航組件實現組件間的導航。
-
圖形
方舟開發框架提供了多種類型圖片的顯示能力和多種自定義繪製的能力,以滿足開發者的自定義繪圖需求,支持繪製形狀、填充顏色、繪製文本、變形與裁剪、嵌入圖片等。
-
動畫
動畫是UI的重要元素之一。優秀的動畫設計能夠極大地提升用户體驗,框架提供了豐富的動畫能力,除了組件內置動畫效果外,還包括屬性動畫、顯式動畫、自定義轉場動畫以及動畫API等,開發者可以通過封裝的物理模型或者調用動畫能力API來實現自定義動畫軌跡。
-
交互事件
交互事件是UI和用户交互的必要元素。方舟開發框架提供了多種交互事件,除了觸摸事件、鼠標事件、鍵盤按鍵事件、焦點事件等通用事件外,還包括基於通用事件進行進一步識別的手勢事件。手勢事件有單一手勢如點擊手勢、長按手勢、拖動手勢、捏合手勢、旋轉手勢、滑動手勢,以及通過單一手勢事件進行組合的組合手勢事件。
2.1 特點
-
開發效率高,開發體驗好
- 代碼簡潔:通過接近自然語義的方式描述UI,不必關心框架如何實現UI繪製和渲染。
- 數據驅動UI變化:讓開發者更專注自身業務邏輯的處理。當UI發生變化時,開發者無需編寫在不同的UI之間進行切換的UI代碼, 開發人員僅需要編寫引起界面變化的數據,具體UI如何變化交給框架。
- 開發體驗好:界面也是代碼,讓開發者的編程體驗得到提升。
-
性能優越
- 聲明式UI前端和UI後端分層:UI後端採用C++語言構建,提供對應前端的基礎組件、佈局、動效、交互事件、組件狀態管理和渲染管線。
- 語言編譯器和運行時的優化:統一字節碼、高效FFI-Foreign Function Interface、AOT-Ahead Of Time、引擎極小化、類型優化等。
-
生態容易快速推進
能夠借力主流語言生態快速推進,語言相對中立友好,有相應的標準組織可以逐步演進。
2.2 整體架構
<center>聲明式開發範式整體架構</center>
-
聲明式UI前端
提供了UI開發範式的基礎語言規範,並提供內置的UI組件、佈局和動畫,提供了多種狀態管理機制,為應用開發者提供一系列接口支持。
-
語言運行時
選用方舟語言運行時,提供了針對UI範式語法的解析能力、跨語言調用支持的能力和TS語言高性能運行環境。
-
聲明式UI後端引擎
後端引擎提供了兼容不同開發範式的UI渲染管線,提供多種基礎組件、佈局計算、動效、交互事件,提供了狀態管理和繪製能力。
-
渲染引擎
提供了高效的繪製能力,將渲染管線收集的渲染指令,繪製到屏幕的能力。
-
平台適配層
提供了對系統平台的抽象接口,具備接入不同系統的能力,如系統渲染管線、生命週期調度等。
2.3 開發流程
通過構建一個簡單的具有頁面跳轉/返回功能的應用(如下圖所示),快速瞭解工程目錄的主要文件,熟悉HarmonyOS應用開發流程。
本例演示使用Stage模型構建ArkTS應用,如果使用FA模型請參考官網。當前主推Stage模型,所以FA模型不再演示。
2.3.1 創建ArkTS工程
前面章節一演示創建過第一個HarmonyOS應用,按相同方法創建項目:
(1)若首次打開DevEco Studio,請點擊Create Project創建工程。如果已經打開了一個工程,請在菜單欄選擇File > New > Create Project來創建一個新工程。
(2)選擇Application應用開發(本文以應用開發為例,Atomic Service對應為元服務開發),選擇模板“Empty Ability”,點擊Next進行下一步配置。
(3)進入配置工程界面,Compile SDK選擇“3.1.0(API 9)”,Model 選擇“Stage”,其他參數保持默認設置即可。
支持使用ArkTS低代碼開方式。
低代碼開發方式具有豐富的UI界面編輯功能,通過可視化界面開發方式快速構建佈局,可有效降低開發者的上手成本並提升開發者構建UI界面的效率。
如需使用低代碼開發方式,請打開上圖中的Enable Super Visual開關。
(4) 點擊Finish,工具會自動生成示例代碼和相關資源,等待工程創建完成。
<center>ArkTS工程目錄結構(Stage模型)</center>
目錄含義解釋:
- AppScope > app.json5:應用的全局配置信息。
-
entry:HarmonyOS工程模塊,編譯構建生成一個HAP包。
- src > main > ets:用於存放ArkTS源碼。
- src > main > ets > entryability:應用/服務的入口。
- src > main > ets > pages:應用/服務包含的頁面。
- src > main > resources:用於存放應用/服務所用到的資源文件,如圖形、多媒體、字符串、佈局文件等。
- src > main > module.json5:Stage模型模塊配置文件。主要包含HAP包的配置信息、應用/服務在具體設備上的配置信息以及應用/服務的全局配置信息。
- build-profile.json5:當前的模塊信息、編譯信息配置項,包括buildOption、targets配置等。其中targets中可配置當前運行環境,默認為HarmonyOS。
- hvigorfile.ts:模塊級編譯構建任務腳本,開發者可以自定義相關任務和代碼實現。
- oh_modules:用於存放三方庫依賴信息。
- build-profile.json5:應用級配置信息,包括簽名、產品配置等。
- hvigorfile.ts:應用級編譯構建任務腳本。
2.3.2 構建第一個頁面
(1)默認界面使用文本組件
工程同步完成後,在“Project”窗口,點擊“entry > src > main > ets > pages”,打開“Index.ets”文件,可以看到頁面由Text組件組成。“Index.ets”文件的示例如下:
// Index.ets
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
(2) 添加按鈕
在默認頁面基礎上,我們添加一個Button組件,作為按鈕響應用户點擊,從而實現跳轉到另一個頁面。“Index.ets”文件的示例如下:
// Index.ets
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按鈕,以響應用户點擊
Button() {
Text('Next')
.fontSize(30)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
}
.width('100%')
}
.height('100%')
}
}
(3) 在編輯窗口右上角的側邊工具欄,點擊Previewer,打開預覽器。第一個頁面效果如下圖所示:
2.4.3 構建第二個頁面
(1)新建第二個頁面文件。在“Project”窗口,打開“entry > src > main > ets ”,右鍵點擊“pages”文件夾,選擇“New > ArkTS File”,命名為“Second”,點擊“Finish”。可以看到文件目錄結構如下:
也可以在右鍵點擊“pages”文件夾時,選擇“New > Page”,則無需手動配置相關頁面路由。
(2) 配置第二個頁面的路由。在“Project”窗口,打開“entry > src > main > resources > base > profile”,在main_pages.json文件中的“src”下配置第二個頁面的路由“pages/Second”。示例如下:
{
"src": [
"pages/Index",
"pages/Second"
]
}
(3) 添加文本及按鈕
參照第一個頁面,在第二個頁面添加Text組件、Button組件等,並設置其樣式。“Second.ets”文件的示例如下:
// Second.ets
@Entry
@Component
struct Second {
@State message: string = 'Hi there'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() {
Text('Back')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
}
.width('100%')
}
.height('100%')
}
}
2.4.4 實現頁面間的跳轉
頁面間的導航可以通過頁面路由router來實現。頁面路由router根據頁面url找到目標頁面,從而實現跳轉。使用頁面路由請導入router模塊。
(1)第一個頁面跳轉到第二個頁面
在第一個頁面中,跳轉按鈕綁定onClick事件,點擊按鈕時跳轉到第二頁。“Index.ets”文件的示例如下:
// Index.ets
// 導入頁面路由模塊
import router from '@ohos.router';
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按鈕,以響應用户點擊
Button() {
Text('Next')
.fontSize(30)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
// 跳轉按鈕綁定onClick事件,點擊時跳轉到第二頁
.onClick(() => {
console.info(`Succeeded in clicking the 'Next' button.`)
// 跳轉到第二頁
router.pushUrl({ url: 'pages/Second' }).then(() => {
console.info('Succeeded in jumping to the second page.')
}).catch((err) => {
console.error(`Failed to jump to the second page.Code is ${err.code}, message is ${err.message}`)
})
})
}
.width('100%')
}
.height('100%')
}
}
(2) 第二個頁面返回到第一個頁面
在第二個頁面中,返回按鈕綁定onClick事件,點擊按鈕時返回到第一頁。“Second.ets”文件的示例如下:
// Second.ets
// 導入頁面路由模塊
import router from '@ohos.router';
@Entry
@Component
struct Second {
@State message: string = 'Hi there'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() {
Text('Back')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
// 返回按鈕綁定onClick事件,點擊按鈕時返回到第一頁
.onClick(() => {
console.info(`Succeeded in clicking the 'Back' button.`)
try {
// 返回第一頁
router.back()
console.info('Succeeded in returning to the first page.')
} catch (err) {
console.error(`Failed to return to the first page.Code is ${err.code}, message is ${err.message}`)
}
})
}
.width('100%')
}
.height('100%')
}
}
(3) 打開“Index.ets”文件,點擊預覽器中的”Refresh“刷新按鈕進行刷新。效果如下圖所示
除了採用預覽方式外,還可以按前面章節講解的通過模擬器或真機進行調試。
《鴻蒙應用開發從入門到項目實戰》系列文章持續更新中,陸續更新AI+編程、企業級項目實戰等原創內容,防止迷路,歡迎關注!