通過編寫計算器學習ArkUI組件
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??
想要程序做什么首先自己要明確自己想要什么,通過分析選題思考程序需要哪些信息,如何與用戶進行交互,以及以什么樣的形式反饋給用戶(即UI設(shè)計),最終通過運行調(diào)試完成整個應用程序的開發(fā)。
一、做什么
做一款多功能的計算器,其中類型包含標準計算器、科學計算器、程序員計算器、房貸計算器等。
二、做成什么樣
計算器給用戶提供多功能選擇,通過按鈕進行交互,文本進行反饋顯示,并通過一系列數(shù)據(jù)處理,最終反饋給用戶正確的值??梢酝ㄟ^一幅圖或者一個演示Demo來確認是否與預期相符,便于不會因為決策導致返工(本節(jié)以標準計算器為例,其他示例不在此處贅述)。
1、分析
將整個頁面分為三塊,標題欄,顯示區(qū),功能按鈕區(qū)。
- 標題欄: 通過點擊圖標切換不同計算器,同時提供歷史記錄查詢。
- 顯示區(qū): 通過兩個文本組件分別顯示錄入計算表達式和計算結(jié)果。
- 功能按鈕區(qū): 功能按鈕區(qū)分為功能按鈕(如清空,回退等),符號按鈕(如加、減等),及數(shù)字按鈕(0-9數(shù)字鍵)。
2、 用到的知識點
對即將實現(xiàn)的標準計算器UI界面分析后,從中提煉出需要用到的技術(shù)。
- 對于實現(xiàn)設(shè)計的UI界面,需要了解ArkUI的【布局約束】。
- 對于三大塊自上而下的布局方式,需要了解【Flex布局】或【Column容器組件】。
- 對于三大塊內(nèi)元素(組件)排列,需要了解【Flex布局】或【Row容器組件】。
- 對于UI界面中點擊選擇,需要了解【Menu控制】。
- 對于UI界面中單個按鈕元素(組件),需要了解【Button組件】和【點擊事件】。
- 對于UI界面中單個文本顯示元素(組件),需要了解【Text組件】和【@State組件狀態(tài)管理】。
三、編寫代碼
1、 分析示例代碼
創(chuàng)建項目和目錄結(jié)構(gòu)已經(jīng)在 了解一些ArkUI概念并熟悉應用的結(jié)構(gòu) 中介紹過了,有需要可以查看。打開index.ets文件,示例代碼實現(xiàn)了頁面居中顯示Hello World,先來了解每行代碼代表的含義。
@Entry
@Component
struct Index {
build() { }
}
1.1 @Entry裝飾器
@Entry 注解(裝飾,我更愿意稱為注解)的自定義組件(在ArkUI中一切皆為組件,使用已有組件組合構(gòu)成頁面)作為頁面的默認入口,也可以理解為頁面的根節(jié)點。當頁面被加載時,首先創(chuàng)建并呈現(xiàn)@Entry注解的組件,一個頁面中有且僅能使用一個@Entry注解,只有使用@Entry注解的組件或子組件,才會在頁面上顯示。
1.2 @Component裝飾器
@Component 注解(裝飾)的代碼塊具有組件化能力,能夠成為一個獨立的組件,這個類型組件也稱為自定義組件,必須在build()方法描述UI結(jié)構(gòu),且不能自定義構(gòu)造函數(shù)。
// 這種寫法錯誤,因為缺少build()方法
// 報錯 struct 'MyComponent' must be at least or at most one 'build' method.
@Component
struct MyComponent {
Flex() {}
}
自定義組件具有以下特點:
- 可組合:可以使用內(nèi)置組件、其他組件、公共屬性和方法組合需要的UI結(jié)構(gòu),比如使用Text和Button組件自定義彈窗組件。
- 可重用:自定義組件可以被其他組件重用,并作為不同的實例在不同的父組件或容器中使用,比如自定義彈窗可以多次重復使用。
- 生命周期:生命周期的回調(diào)方法可以在組件中配置,用于業(yè)務邏輯處理。
- 數(shù)據(jù)驅(qū)動更新:由狀態(tài)變量的數(shù)據(jù)驅(qū)動,實現(xiàn)UI自動更新。
1.3 build()函數(shù)(方法)
build() 滿足Build構(gòu)造器接口定義,用于定義組件的聲明式UI描述。在build方法中以聲明式方式進行組合自定義組件或系統(tǒng)內(nèi)置組件,在組件創(chuàng)建和更新場景中都會調(diào)用build方法。build方法僅支持組合組件,使用渲染控制語句。
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
}
2、 Flex容器組件和Flex布局
通過3.1小節(jié)的了解,我們可以在被@Entry和@Componet注解的代碼塊中的build函數(shù)中使用框架提供的內(nèi)置基本組件和布局(容器)組件來構(gòu)建自定義組件并顯示到頁面中。當然我們也可以不適用容器組件而直接使用基本組件來構(gòu)建頁面元素,但不推薦這種做法,組件過多無法有效的進行布局控制。如下代碼與示例效果相同:
@Entry
@Component
struct Index {
build() {
Text('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
// Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
// Text('Hello World')
// .fontSize(50)
// .fontWeight(FontWeight.Bold)
// }
// .width('100%')
// .height('100%')
}
}
為了滿足復雜的、可控的、已維護的UI界面,我們必須對容器組件有一定的了解,在不同的場景下使用不同的容器組件,可以快速有效的構(gòu)建符合需要的UI界面。接下來使用Flex容器組件實現(xiàn)標準計算器三大塊分隔。
2.1 Flex容器組件
Flex容器組件稱為彈性布局組件,通過簡單靈活的控制子組件、并具備響應式,可以實現(xiàn)各種頁面布局,因此Flex布局作為首選布局。
Flex容器組件具有以下特點:
- 四種子組件布局模式:Row(行方向)、RowReverse(反Row)、Column(列方向)、ColumnReverse(反列)。
- 容器元素單行/多行顯示:NoWrap(單行/列布局)、Wrap(多行/列布局)、WrapReverse(反向多行/列布局),均允許元素超出容器。
- 兩種對齊方式:主軸對齊方式和交叉軸對齊方式。
- 僅當父組件為Flex容器組件時,還可以設(shè)置子組件在主軸方向上基準尺寸(flexBasis)、子組件在容器剩余空間的比例(flexGrow)、壓縮尺寸分配給子組件(flexShrink)以及設(shè)置子組件在容器中交叉軸對齊方式(alignSelf)。
@Entry
@Component
struct Index {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center }) {
Text('主軸與行方向一致作為布局模式')
.fontSize(9)
.fontColor('#CCCCCC')
.width('90%')
// 主軸與行方向一致作為布局模式
Flex({direction: FlexDirection.Row, wrap: FlexWrap.NoWrap,
justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
Text('A').flexGrow(2).height(100).fontSize(50)
.backgroundColor('#F2F2F2').textAlign(TextAlign.Center)
Text('B').flexGrow(1).height(100).fontSize(50)
.backgroundColor('#E2E2E2').textAlign(TextAlign.Center)
}
.width('100%').height(120).padding(10)
Text('與Row方向相反方向進行布局')
.fontSize(9)
.fontColor('#CCCCCC')
.width('90%')
// 與Row方向相反方向進行布局
Flex({direction: FlexDirection.RowReverse, wrap: FlexWrap.NoWrap,
justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
Text('A').flexGrow(2).height(100).fontSize(50)
.backgroundColor('#F2F2F2').textAlign(TextAlign.Center)
Text('B').flexGrow(1).height(100).fontSize(50)
.backgroundColor('#E2E2E2').textAlign(TextAlign.Center)
}
.width('100%').height(120).padding(10)
Text('主軸與列方向一致作為布局模式')
.fontSize(9)
.fontColor('#CCCCCC')
.width('90%')
// 主軸與列方向一致作為布局模式
Flex({direction: FlexDirection.Column, wrap: FlexWrap.NoWrap,
justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
Text('A').flexGrow(2).width('100%').fontSize(50)
.backgroundColor('#F2F2F2').textAlign(TextAlign.Center)
Text('B').flexGrow(1).width('100%').fontSize(50)
.backgroundColor('#E2E2E2').textAlign(TextAlign.Center)
}
.width('100%').height(200).padding(10)
Text('與Column相反方向進行布局')
.fontSize(9)
.fontColor('#CCCCCC')
.width('90%')
// 與Column相反方向進行布局
Flex({direction: FlexDirection.ColumnReverse, wrap: FlexWrap.NoWrap,
justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
Text('A').flexGrow(2).width('100%').fontSize(50)
.backgroundColor('#F2F2F2').textAlign(TextAlign.Center)
Text('B').flexGrow(1).width('100%').fontSize(50)
.backgroundColor('#E2E2E2').textAlign(TextAlign.Center)
}
.width('100%').height(200).padding(10)
}
.width('100%')
.height('100%')
}
}
2.2 標準計算器Flex布局實現(xiàn)
通過Flex容器布局構(gòu)建頁面,子組件以三個Flex容器組件為主,占比分別為1、2、4,并使用不同的背景色做簡單的區(qū)域劃分,代碼如下:
@Entry
@Component
struct Index {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center }) {
// 頂部功能按鈕
Flex({direction: FlexDirection.Row}) {}
.flexGrow(1)
.width('100%')
.backgroundColor('#F2F2F2')
// 回顯及結(jié)果顯示區(qū)
Flex({direction: FlexDirection.Column}) {}
.flexGrow(2)
.width('100%')
.backgroundColor('#FFFFFF')
// 功能按鈕、符號按鈕、數(shù)字按鈕
Flex({direction: FlexDirection.Column}) {}
.flexGrow(4)
.width('100%')
.backgroundColor('#E5E5E5')
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
小結(jié)
這并不是完結(jié),而是開始。本篇幅描述了從需求開始一步步到代碼實現(xiàn);從設(shè)計圖到代碼實現(xiàn);從技術(shù)要點到代碼實現(xiàn)。從學到用,從用到學,逐漸掌握ArkUI框架的ets項目開發(fā),下一篇將繼續(xù)本篇幅的內(nèi)容。
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??