鴻蒙開發—學習聲明式UI

基本UI描述

ArkTS通過裝飾器@Component和@Entry裝飾struct關鍵字聲明的數據結構,構成一個自定義組件。自定義組件中提供了一個build函數,開發者需在該函數內以鏈式調用的方式進行基本的UI描述,UI描述的方法請參考UI描述規范。

基本概念

  • struct:自定義組件可以基于struct實現,不能有繼承關系,對于struct的實例化,可以省略new。
  • 裝飾器:裝飾器給被裝飾的對象賦予某一種能力,其不僅可以裝飾類或結構體,還可以裝飾類的屬性。多個裝飾器可以疊加到目標元素上,定義在同一行中或者分開多行,推薦分開多行定義。
less復制代碼@Entry
@Component
struct MyComponent {
}
  • build函數:自定義組件必須定義build函數,并且禁止自定義構造函數。build函數滿足Builder構造器接口定義,用于定義組件的聲明式UI描述。
typescript復制代碼interface Builder {build: () => void
}
  • @Component:裝飾struct,結構體在裝飾后具有基于組件的能力,需要實現build方法來創建UI。
  • @Entry: 裝飾struct,組件被裝飾后作為頁面的入口,頁面加載時將被渲染顯示。
  • @Preview:裝飾struct, 用@Preview裝飾的自定義組件可以在DevEco Studio的預覽器上進行實時預覽,加載頁面時,將創建并顯示@Preview裝飾的自定義組件。

說明: 在單個源文件中,最多可以使用10個@Preview裝飾自定義組件,更多說明請參考查看ArkTS組件預覽效果。

  • 鏈式調用:以 “.” 鏈式調用的方式配置UI組件的屬性方法、事件方法等。

UI描述規范

無參數構造配置

如果組件的接口定義中不包含必選構造參數,組件后面的“()”中不需要配置任何內容。例如,Divider組件不包含構造參數:

scss復制代碼Column() {Text('item 1')Divider()Text('item 2')
}

有參數構造配置

如果組件的接口定義中包含構造參數,則在組件后面的“()”中可配置相應參數,參數可以使用常量進行賦值。

例如:

  • Image組件的必選參數src:
rust
復制代碼Image('https://xyz/test.jpg')
  • Text組件的參數content,該參數非必選,即配置或不配置均可:
scss
復制代碼Text('test')

變量或表達式也可以用于參數賦值,其中表達式返回的結果類型必須滿足參數類型要求,變量的定義詳見頁面級變量的狀態管理與應用級變量的狀態管理。例如,設置變量或表達式來構造Image和Text組件的參數:

kotlin復制代碼Image(this.imagePath)
Image('https://' + this.imageUrl)
Text(`count: ${this.count}`)

屬性配置

使用屬性方法配置組件的屬性,屬性方法緊隨組件,并用"."運算符連接。

  • 配置Text組件的字體大小屬性:
scss復制代碼Text('test').fontSize(12)
  • 使用"."運算符進行鏈式調用并同時配置組件的多個屬性,如下所示:
scss復制代碼Image('test.jpg').alt('error.jpg')    .width(100)    .height(100)
  • 除了直接傳遞常量參數外,還可以傳遞變量或表達式,如下所示:
kotlin復制代碼Text('hello').fontSize(this.size)
Image('test.jpg').width(this.count % 2 === 0 ? 100 : 200)    .height(this.offset + 100)
  • 對于系統內置組件,框架還為其屬性預定義了一些枚舉類型供開發人員調用,枚舉類型可以作為參數傳遞,且必須滿足參數類型要求。例如,可以按以下方式配置Text組件的顏色和字體屬性:
scss復制代碼Text('hello').fontSize(20).fontColor(Color.Red).fontWeight(FontWeight.Bold)

事件配置

通過事件方法可以配置組件支持的事件,事件方法緊隨組件,并用"."運算符連接。

  • 使用lambda表達式配置組件的事件方法:
javascript復制代碼Button('add counter').onClick(() => {this.counter += 2})
  • 使用匿名函數表達式配置組件的事件方法,要求使用bind,以確保函數體中的this引用包含的組件:
javascript復制代碼Button('add counter').onClick(function () {this.counter += 2}.bind(this))
  • 使用組件的成員函數配置組件的事件方法:
kotlin復制代碼myClickHandler(): void {this.counter += 2
}
?
...
?
Button('add counter').onClick(this.myClickHandler.bind(this))

子組件配置

對于支持子組件配置的組件,例如容器組件,在"{ … }"里為組件添加子組件的UI描述。Column、Row、Stack、Grid、List等組件都是容器組件。

  • 以下是簡單的Column示例:
scss復制代碼Column() {Text('Hello').fontSize(100)Divider()Text(this.myText).fontSize(100).fontColor(Color.Red)
}
  • 容器組件之間也可以互相嵌套,實現相對復雜的多級嵌套效果:
scss復制代碼Column() {Row() {Image('test1.jpg').width(100).height(100)Button('click +1').onClick(() => {console.info('+1 clicked!')})}
?Divider()Row() {Image('test2.jpg').width(100).height(100)Button('click +2').onClick(() => {console.info('+2 clicked!')})}
?Divider()Row() {Image('test3.jpg').width(100).height(100)Button('click +3').onClick(() => {console.info('+3 clicked!')})}
}

動態構建UI元素

基本UI描述介紹的是如何創建一個內部UI結構固定的自定義組件,為了滿足開發者自定義組件內部UI結構的需求,ArkTS同時提供了動態構建UI元素的能力。

@Builder

可通過@Builder裝飾器進行描述,該裝飾器可以修飾一個函數,此函數可以在build函數之外聲明,并在build函數中或其他@Builder修飾的函數中使用,從而實現在一個自定義組件內快速生成多個布局內容。使用方式如下面示例所示。

kotlin復制代碼// xxx.ets
@Component
struct CompB {@State CompValue: string = ''
?aboutToAppear() {console.info('CompB aboutToAppear.')}
?aboutToDisappear() {console.info('CompB aboutToDisappear.')}
?build() {Column() {Button(this.CompValue).margin(5)}}
}
?
@Entry
@Component
struct CompA {size1: number = 100@State CompValue1: string = "Hello,CompValue1"@State CompValue2: string = "Hello,CompValue2"@State CompValue3: string = "Hello,CompValue3"
?// @Builder裝飾的函數CompC內使用自定義組件CompB@Builder CompC(value: string) {CompB({ CompValue: value })}
?@Builder SquareText(label: string) {Text(label).fontSize(18).width(1 * this.size1).height(1 * this.size1)}
?// @Builder裝飾的函數RowOfSquareTexts內使用@Builder裝飾的函數SquareText@Builder RowOfSquareTexts(label1: string, label2: string) {Row() {this.SquareText(label1)this.SquareText(label2)}.width(2 * this.size1).height(1 * this.size1)}
?build() {Column() {Row() {this.SquareText("A")this.SquareText("B")}.width(2 * this.size1).height(1 * this.size1)
?this.RowOfSquareTexts("C", "D")Column() {// 使用三次@Builder裝飾的自定義組件this.CompC(this.CompValue1)this.CompC(this.CompValue2)this.CompC(this.CompValue3)}.width(2 * this.size1).height(2 * this.size1)}.width(2 * this.size1).height(2 * this.size1)}
}

@BuilderParam8+

@BuilderParam裝飾器用于修飾自定義組件內函數類型的屬性(例如:@BuilderParam noParam: () => void),并且在初始化自定義組件時被@BuilderParam修飾的屬性必須賦值。

引入動機 當開發者創建自定義組件,并想對該組件添加特定功能時(例如在自定義組件中添加一個點擊跳轉操作)。若直接在組件內嵌入事件方法,將會導致所有引入該自定義組件的地方均增加了該功能。為解決此問題,引入了@BuilderParam裝飾器,此裝飾器修飾的屬性值可為@Builder裝飾的函數,開發者可在初始化自定義組件時對此屬性進行賦值,為自定義組件增加特定的功能。

參數初始化組件

通過參數初始化組件時,將@Builder裝飾的函數賦值給@BuilderParam修飾的屬性,并在自定義組件內調用該屬性值。若@BuilderParam修飾的屬性在進行賦值時不帶參數(如:noParam: this.specificNoParam),則此屬性的類型需定義為無返回值的函數(如:@BuilderParam noParam: () => void);若帶參數(如:withParam: this.SpecificWithParam(‘WithParamA’)),則此屬性的類型需定義成any(如:@BuilderParam withParam: any)。

scss復制代碼// xxx.ets
@Component
struct CustomContainer {header: string = ''@BuilderParam noParam: () => void@BuilderParam withParam: anyfooter: string = ''
?build() {Column() {Text(this.header).fontSize(30)this.noParam()this.withParam()Text(this.footer).fontSize(30)}}
}
?
@Entry
@Component
struct CustomContainerUser {@Builder specificNoParam() {Column() {Text('noParam').fontSize(30)}}
?@Builder SpecificWithParam(label: string) {Column() {Text(label).fontSize(30)}}
?build() {Column() {CustomContainer({header: 'HeaderA',noParam: this.specificNoParam,withParam: this.SpecificWithParam('WithParamA'),footer: 'FooterA'})Divider().strokeWidth(3).margin(10)CustomContainer({header: 'HeaderB',noParam: this.specificNoParam,withParam: this.SpecificWithParam('WithParamB'),footer: 'FooterB'})}}
}

尾隨閉包初始化組件

在自定義組件中使用@BuilderParam修飾的屬性時也可通過尾隨閉包進行初始化(在初始化自定義組件時,組件后緊跟一個大括號“{}”形成尾隨閉包場景(CustomContainer(){})。開發者可把尾隨閉包看做一個容器,向其中填充內容,如在閉包內增加組件({Column(){…}),閉包內語法規范與build函數一致。此場景下自定義組件內有且僅有一個使用@BuilderParam修飾的屬性。

示例:在閉包內添加Column組件并設置點擊事件,在Column組件內調用@Builder修飾的specificParam函數,點擊Column組件后將自定義組件CustomContainer中header的屬性值由“header”改變為“changeHeader”。在初始化自定義組件CustomContainer時,尾隨閉包的內容會被賦值給@BuilderParam修飾的closer屬性。

scss復制代碼// xxx.ets
@Component
struct CustomContainer {header: string = ''@BuilderParam closer: () => void
?build() {Column() {Text(this.header).fontSize(30)this.closer()}}
}
?
@Builder function specificParam(label1: string, label2: string) {Column() {Text(label1).fontSize(30)Text(label2).fontSize(30)}
}
?
@Entry
@Component
struct CustomContainerUser {@State text: string = 'header'
?build() {Column() {CustomContainer({header: this.text,}) {Column() {specificParam('testA', 'testB')}.backgroundColor(Color.Yellow).onClick(() => {this.text = 'changeHeader'})}}}
}

@Styles

ArkTS為了避免開發者對重復樣式的設置,通過@Styles裝飾器可以將多個樣式設置提煉成一個方法,直接在組件聲明時調用,通過@Styles裝飾器可以快速定義并復用自定義樣式。當前@Styles僅支持通用屬性。

@Styles可以定義在組件內或組件外,在組件外定義時需在方法名前面添加function關鍵字,組件內定義時則不需要添加function關鍵字。

scss復制代碼// xxx.ets
@Styles function globalFancy () {.width(150).height(100).backgroundColor(Color.Pink)
}
?
@Entry
@Component
struct FancyUse {@Styles componentFancy() {.width(100).height(200).backgroundColor(Color.Yellow)}
?build() {Column({ space: 10 }) {Text('FancyA').globalFancy().fontSize(30)Text('FancyB').globalFancy().fontSize(20)Text('FancyC').componentFancy().fontSize(30)Text('FancyD').componentFancy().fontSize(20)}}
}

@Styles還可以在StateStyles屬性內部使用,在組件處于不同的狀態時賦予相應的屬性。

在StateStyles內可以直接調用組件外定義的@Styles方法,但需要通過this關鍵字調用組件內定義的@Styles方法。

less復制代碼// xxx.ets
@Styles function globalFancy () {.width(120).height(120).backgroundColor(Color.Green)
}
?
@Entry
@Component
struct FancyUse {@Styles componentFancy() {.width(80).height(80).backgroundColor(Color.Red)}
?build() {Row({ space: 10 }) {Button('Fancy').stateStyles({normal: {.width(100).height(100).backgroundColor(Color.Blue)},disabled: this.componentFancy,pressed: globalFancy})}}
}

@Extend

@Extend裝飾器將新的屬性方法添加到Text、Column、Button等內置組件上,通過@Extend裝飾器可以快速地擴展原生組件。@Extend不能定義在自定義組件struct內。

less復制代碼// xxx.ets
@Extend(Text) function fancy (fontSize: number) {.fontColor(Color.Red).fontSize(fontSize).fontStyle(FontStyle.Italic).fontWeight(600)
}
?
@Entry
@Component
struct FancyUse {build() {Row({ space: 10 }) {Text("Fancy").fancy(16)Text("Fancy").fancy(24)Text("Fancy").fancy(32)}}
}

說明:

  • @Extend裝飾器不能定義在自定義組件struct內。
  • @Extend裝飾器內僅支持屬性方法設置。

@CustomDialog

@CustomDialog裝飾器用于裝飾自定義彈窗組件,使得彈窗可以動態設置內容及樣式。

scss復制代碼// xxx.ets
@CustomDialog
struct DialogExample {controller: CustomDialogControlleraction: () => void
?build() {Row() {Button('Close CustomDialog').onClick(() => {this.controller.close()this.action()})}.padding(20)}
}
?
@Entry
@Component
struct CustomDialogUser {dialogController: CustomDialogController = new CustomDialogController({builder: DialogExample({ action: this.onAccept }),cancel: this.existApp,autoCancel: true});
?onAccept() {console.info('onAccept');}
?existApp() {console.info('Cancel dialog!');}
?build() {Column() {Button('Click to open Dialog').onClick(() => {this.dialogController.open()})}}
}

插件分享

1.Chinese

漢化插件,讓國人開發者更加如魚得水

2.Atom Material File Icons

提供文件和文件夾圖標支持,讓你的項目看的更加賞心悅目

3.One Dark theme

一款暗色系主題插件,非常適合在晚上偷偷卷代碼

4.Material Theme UI

一款多色系主題插件,自2021年后需要收費使用,本節文末提供下載鏈接

5.Rainbow Brackets

括號匹配彩虹色

6.Indent Rainbow

代碼縮進提供色彩支持,非常適合控制代碼格式

本文主要簡單解析了在鴻蒙開發當中,聲明式UI講解。有更多的鴻蒙開發學習,可以查看《鴻蒙開發者進階》點擊可以查看詳細的內容板塊。

以上為一張學習路線略縮圖,高清完整版請移至主業查看獲取。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/213116.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213116.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213116.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GZ029 智能電子產品設計與開發賽題第4套

2023年全國職業院校技能大賽高職組 “GZ029智能電子產品設計與開發”賽項賽卷四 題目:模擬工業傳送帶物品檢測系統的設計與開發 1 競賽任務 在智能電視機上播放工業傳送帶傳輸物品視頻,模擬工業傳送帶物品檢測系統(以下簡稱物品檢測系統&…

DALI1.0學習——BIT解碼

最近在學習DALI調光相關知識并下載了Microchip提供的基于ATMega88PA的軟件工程及硬件設計參考方案。寫這些文章的目的就是把自己對知識的理解作一些梳理。 芯片廠果然專業,考慮得相當周到,為了芯片銷量連軟件和硬件方案全都提供了。芯片廠關于DALI1.0實…

【unity小技巧】實現槍武器隨鏡頭手臂搖擺效果

文章目錄 前言方法一、改變武器位置方法二、改變武器旋轉結語完結 前言 如果我們視角移動轉向,武器如果不跟著進行搖擺,會感覺我們的動作很生硬,特別是射擊類游戲,如下 實現武器搖擺這里主要分享兩種實現方法,一種是…

xtu oj 1271 color

題目描述 Alice在玩一個游戲,她在一個mn的格子里,隨機涂黑k個格子。然后她每次可以把一行或者一列的格子染成紅色,但是這一行中不能有黑色的格子。 請問她最多能把多少個格子涂成紅色? 輸入 第一行是一個整數T(T≤100)&#xf…

華為OD機試 - 數的分解(Java JS Python C)

題目描述 給定一個正整數 n,如果能夠分解為 m(m > 1)個連續正整數之和,請輸出所有分解中,m最小的分解。 如果給定整數無法分解為連續正整數,則輸出字符串"N"。 輸入描述 輸入數據為一整數,范圍為 (1, 2^30] 輸出描述 比如輸入為: 21 輸出: 21=10+11 …

SSD數據在寫入NAND之前為何要隨機化?-Part1

SSD的存儲介質是什么,它就是NAND閃存。那你知道NAND閃存是怎么工作的嗎?其實,它就是由很多個晶體管組成的。這些晶體管里面存儲著電荷,代表著我們的二進制數據,要么是“0”,要么是“1”。NAND閃存原理上是一…

唯創知音WT588F02B語音芯片在電子針療儀中的聲音播放提示應用

在醫療技術領域,電子針療儀作為一種非侵入性的治療設備,被廣泛應用于各種疼痛管理和康復治療。然而,操作電子針療儀需要一定的專業知識和經驗,以確保安全有效的治療。為了解決這一難題,唯創知音WT588F02B語音芯片被應用…

0基礎學java-day14-(集合)

一、集合 前面我們保存多個數據使用的是數組,那么數組有不足的地方,我們分析一下 1.數組 2 集合 數據類型也可以不一樣 3.集合的框架體系 Java 的集合類很多,主要分為兩大類,如圖 :[背下來] package com.hspedu.c…

設計模式之GoF23介紹

深入探討設計模式:構建可維護、可擴展的軟件架構 一、設計模式的背景1.1 什么是設計模式1.2 設計模式的歷史 二、設計模式的分類2.1 創建型模式2.2 結構型模式2.3 行為型模式 三、七大設計原則四、設計模式關系結論 :rocket: :rocket: :rocket: 在軟件開發領域&…

算法:爬樓梯(迭代和動態規劃)

迭代 時間復雜度 O(n) 空間復雜度 O(1) /*** param {number} n* return {number}*/ var climbStairs function(n) {let l 0, r 0 , sum 1for(let i1; i<n; i){l rr sumsum l r}return sum }; 動態規劃 時間復雜度 O(n) 空間復雜度 O(n) /*** param {number} n* r…

Memcached學習

一、概念 Memcached是一個開源的&#xff0c;高性能的內存緩存軟件&#xff0c;從名稱上看Mem就是內存&#xff0c;二cache是緩存。作用通過在事先規劃好的內存空間中臨時緩存數據庫中的各類數據&#xff0c;以達到減少業務對數據庫的直接高并發訪問&#xff0c;從而達到提升數…

【密碼學基礎】Diffie-Hellman密鑰交換協議

DH介紹 Diffie-Hellman密鑰協議算法是一種確保共享密鑰安全穿越不安全網絡的方法。 這個機制的巧妙在于需要安全通信的雙方可以用這個方法確定對稱密鑰&#xff0c;然后可以用這個密鑰進行加密和解密。 但是注意&#xff0c;這個密鑰交換協議 只能用于密鑰的交換&#xff0c;而…

Java面試題(每天10題)-------連載(45)

Dubbo篇 1、Dubbo的服務調用流程 2、Dubbo支持那種協議&#xff0c;每種協議的應用場景&#xff0c;優缺點&#xff1f; dubbo&#xff1a; 單一長連接和 NIO 異步通訊&#xff0c;適合大并發小數據量的服務調用&#xff0c;以及消費者遠大于提供者。傳輸協議 TCP&#xff0c;…

Proteus仿真--射擊小游戲仿真設計

本文介紹基于proteus射擊小游戲仿真設計&#xff08;完整仿真源文件及代碼見文末鏈接&#xff09; 仿真圖如下 K1-K4為4個按鍵&#xff0c;用于上移、下移、確認等&#xff0c;模擬單機游戲 仿真運行視頻 Proteus仿真--射擊小游戲仿真設計 附完整Proteus仿真資料代碼資料 …

ArcGIS界面顯示分辨率調整

因為電腦顯示分辨率的問題呢&#xff0c;ArcGIS的界面顯示會字體顯示不合適&#xff0c;出現模糊情況&#xff0c;這時候只需要做個簡單的操作設置一下便可以解決&#xff01; 1、右鍵ArcMap的快捷啟動方式。 2、對應選擇兼容性——>更高DPI設置——>勾選替代DPI縮放行為…

自然場景圖像中的文本檢測綜述

摘 要 本文對自然場景文本檢測問題及其方法的研究進展進行了綜述. 首先, 論述了自然場景文本的特點、自然場景文本檢測技術的研究背景、現狀以及主要技術路線. 其次, 從傳統文本檢測以及深度學習文本檢測的視角出發, 梳理、分析并比較了各類自然場景文本檢測方法的優缺點, 并介…

體系化學習運籌學基礎算法的實踐和總結

文章目錄 引言目標設計目標實踐文章匯總經驗總結一則預告 引言 眨眼間已經12月了&#xff0c;眼看著2023年馬上要過完了。 女朋友最近總說&#xff0c;工作以后感覺時間過的好快。事實上&#xff0c;我也是這么認為的。年紀越大&#xff0c;越會擔心35歲危機的降臨。所以&…

Xubuntu16.04系統中使用EDIMAX EW-7822UAC無線網卡開啟5G自發AP

目錄 1.關于 EDIMAX EW-7822UAC2.驅動安裝3.查看無線網卡信息3.通過create_ap配置5G自發AP 1.關于 EDIMAX EW-7822UAC 官網介紹 https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/wireless_adapters_ac1200_dual-band/ew-7822uac/ 詳細參數…

Python開發運維:Python項目發布到K8S集群

目錄 一、實驗 1.Python項目發布到K8S集群 一、實驗 1.Python項目發布到K8S集群 &#xff08;1&#xff09;獲取應用程序代碼 #把hello-python.tar.gz壓縮包上傳到k8s控制節點master1的root下&#xff0c;手動解壓 tar zxvf hello-python.tar.gz &#xff08;2&#xff0…

【Linux】進程周邊001之進程概念

&#x1f440;樊梓慕&#xff1a;個人主頁 &#x1f3a5;個人專欄&#xff1a;《C語言》《數據結構》《藍橋杯試題》《LeetCode刷題筆記》《實訓項目》《C》《Linux》 &#x1f31d;每一個不曾起舞的日子&#xff0c;都是對生命的辜負 目錄 前言 1.基本概念 2.描述進程-PCB…