前言
1. 常用容器組件
- Column:沿垂直方向布局的容器組件嘿般。
- Row:沿水平方向布局的容器組件。
- Stack:堆疊容器組件重归,子組件按照順序依次入棧至壤,后一個子組件覆蓋前一個子組件鹏控。
- Flex:以彈性方式布局子組件的容器組件。
說明:
1.Flex組件主軸默認(rèn)不設(shè)置時撐滿父容器肤寝,Column当辐、Row組件主軸不設(shè)置時默認(rèn)是跟隨子節(jié)點(diǎn)大小。
2.Flex組件在渲染時存在二次布局過程醒陆,因此在對性能有嚴(yán)格要求的場景下建議使用Column瀑构、Row代替。
2. 列表組件
- List:列表包含一系列相同寬度的列表項(xiàng)刨摩,適合連續(xù)寺晌、多行呈現(xiàn)同類數(shù)據(jù),例如圖片和文本澡刹。
- ListItem:用來展示具體列表項(xiàng)呻征,必須配合List來使用。
- ListItemGroup:用來展示分組列表項(xiàng)的組件罢浇,必須配合List組件來使用陆赋。
3. 宮格組件
- Grid:網(wǎng)格容器組件,由“行”和“列”分割的單元格所組成嚷闭,通過指定“項(xiàng)目”所在的單元格做出各種各樣的布局攒岛。
- GridItem:網(wǎng)格容器中單項(xiàng)內(nèi)容容器。
4. 文本與輸入組件
- Text:顯示一段文本的組件胞锰。
- Span:作為Text組件的子組件灾锯,用于顯示行內(nèi)文本片段的組件。
- TextInput:單行文本輸入框組件嗅榕。
- TextArea:多行文本輸入框組件顺饮,當(dāng)輸入的文本內(nèi)容超過組件寬度時會自動換行顯示。
- RichText:富文本組件凌那,解析并顯示HTML格式文本兼雄。
5. 空白與分隔組件
- Blank:空白填充組件,在容器主軸方向上帽蝶,空白填充組件具有自動填充容器空余部分的能力赦肋。僅當(dāng)父組件為Row/Column時生效。
- Divider:分隔器組件嘲碱,分隔不同內(nèi)容塊/內(nèi)容元素金砍。
一、構(gòu)建第一個頁面
// Index.ets
// 裝飾器(帶@修飾)麦锯∷〕恚可以用來裝飾類結(jié)構(gòu)、方法扶欣、變量鹅巍,如:@Entry千扶、@Component、@State等
@Entry // @Entry 標(biāo)記當(dāng)前組件是入口組件骆捧,即這個組件代表一個頁面可以被獨(dú)立訪問顯示澎羞。沒有這個裝飾器的組件就是普通組件,不能單獨(dú)顯示敛苇,只能被其它頁面引用妆绞,做頁面元素的封裝(相當(dāng)于子視圖)
@Component // @Component 標(biāo)記這個結(jié)構(gòu)體是一個自定義組件
// 這個結(jié)構(gòu)體在ArkTS中稱為,自定義組件:可復(fù)用的UI單元
struct Index {
// @State 用來標(biāo)記一個變量是狀態(tài)變量枫攀,值變化時會觸發(fā)UI刷新
// 聲明式UI特點(diǎn):狀態(tài)數(shù)據(jù)變化驅(qū)動頁面UI自動刷新
@State message: string = 'Hello World'
// 構(gòu)建組件內(nèi)容括饶,UI描述:其內(nèi)部以聲明式方式描述UI結(jié)構(gòu)
build() {
// 內(nèi)置組件:ArkUI提供的組件
// 容器組件:用來完成頁面布局,例如:Row来涨、Column
// 基礎(chǔ)組件:自帶樣式和功能的頁面元素图焰,例如:Text
Row() {
Column() {
Text(this.message)
// 屬性方法:設(shè)置組件的UI樣式
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 事件方法:設(shè)置組件的事件回調(diào)(傳一個回調(diào)函數(shù))
.onClick(() => {
// ...處理事件
this.message = 'Hello ArkTS!'
})
}
.width('100%')
}
.height('100%')
}
}
二、Image組件
- 組件使用
// 需要配置網(wǎng)絡(luò)訪問權(quán)限蹦掐,才能請求網(wǎng)絡(luò)資源
Image('https://gbres.dfcfw.com/Files/picture/20240107/A647B2359640C398075289DFB100768F_w707h782.jpg')
// 指定圖片寬度技羔,高度會自動按圖片寬高比自動縮放
.width(300) // 數(shù)字格式,如:300vp卧抗,會有一個默認(rèn)單位vp(虛擬像素:不是真正屏幕像素藤滥,會根據(jù)設(shè)備像素密度進(jìn)行換算,確保在不同設(shè)備上視覺大小一樣)
//.width('100%') // 字符串格式社裆,如:'100%'超陆,百分比模式(根據(jù)設(shè)備大小自動伸縮)
- 訪問控制權(quán)限申請
在module.json5文件中添加如下內(nèi)容:
{
"module": {
// 配置權(quán)限(系統(tǒng)權(quán)限、用戶權(quán)限)
"requestPermissions": [
{
// 配置網(wǎng)絡(luò)權(quán)限(屬于系統(tǒng)權(quán)限浦马,只需要配置name即可)
"name": "ohos.permission.INTERNET"
}
],
... ...
}
三、Text組件
注意:base目錄是默認(rèn)目錄张漂,在讀取本地資源文件String時晶默,會優(yōu)先匹配限定詞目錄(國際化),匹配不到再去base目錄航攒。
四磺陡、TextInput組件
// 常見數(shù)據(jù)類型轉(zhuǎn)換
let text = '200'
let num = parseInt(text) // 字符串 轉(zhuǎn) 數(shù)字
let string = num.toFixed(0) // 數(shù)字 轉(zhuǎn) 字符串(保留0位小數(shù))
五、Button組件
六漠畜、Slider組件
七币他、頁面布局組件
- <Column>容器(列容器,縱向布局憔狞,從上到下排列)
- <Row>容器(行容器蝴悉,橫向布局,從左到右排列)
-
布局示例
-
justifyContent:子元素在主軸方向的對齊方式
-
alignItems:子元素在交叉軸方向的對齊方式
-
案例
@Entry
@Component
struct ImagePage {
@State imageWidth: number = 150
build() {
Column() {
Row() {
Image('https://gbres.dfcfw.com/Files/picture/20240107/A647B2359640C398075289DFB100768F_w707h782.jpg')
.width(this.imageWidth)
.interpolation(ImageInterpolation.High)
}
.width('100%')
.height(300)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.backgroundColor('#f1f1f1')
Row() {
Text('圖片寬度:')
.fontSize(20)
TextInput({ placeholder: '請輸入圖片寬度', text: this.imageWidth.toFixed(0) })
.type(InputType.Number)
.onChange(value => {
this.imageWidth = parseInt(value)
})
.backgroundColor('#f1f1f1')
.fontSize(20)
.width(200)
}
.width('100%')
.margin({top: 30})
.padding({left: 15, right: 15})
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#f1f1f1')
// 分割線
Divider()
Row() {
Button('縮小')
.width(88)
.fontSize(20)
.onClick(value => {
if (this.imageWidth >= 100) {
this.imageWidth -= 20
}
})
Button('放大')
.width(80)
.fontSize(20)
.onClick(value => {
if (this.imageWidth <= 300) {
this.imageWidth += 20
}
})
}
.width('100%')
.margin({top: 30})
.justifyContent(FlexAlign.SpaceEvenly)
.backgroundColor('#f1f1f1')
Row() {
Slider({
min: 100,
max: 300,
value: this.imageWidth,
step: 20
})
.blockColor('#bbccdd')
.trackThickness(8)
.showTips(true)
.showSteps(true)
.onChange(value => {
this.imageWidth = value
})
}
.margin({top: 30})
.backgroundColor('#f1f1f1')
}
.width('100%')
.height('100%')
.padding(20)
}
}
- 渲染控制(列表渲染瘾敢、條件渲染)
- 提示:其中的
index?
拍冠、keyGenerator?
是可選參數(shù)尿这,可以不寫
八、List復(fù)雜容器
九庆杜、自定義組件
-
@Component
自定義組件:是將代碼封裝成組件射众,通過導(dǎo)出導(dǎo)入方式進(jìn)行使用。方便代碼復(fù)用晃财,使代碼更加簡潔叨橱。
// 自定義一個標(biāo)題欄組件
@Component
// 導(dǎo)出組件,方便其它文件導(dǎo)入使用
export struct Header {
// ResourceStr:是 string | Resource的別名断盛。表示既可以直接傳字符串罗洗,又可以傳本地資源字符串(string.json中的內(nèi)容)
private title: ResourceStr = ''
build() {
Row({space: 8}) {
Image($r('app.media.icon'))
.width(30)
Text(this.title)
.fontSize(28)
.fontWeight(FontWeight.Bold)
Blank() // 空白組件,相當(dāng)于彈簧效果郑临,撐滿剩余空間栖博,將圖標(biāo)擠到最右邊去
Image($r('app.media.icon'))
.width(30)
}
.width('100%')
}
}
// 在其它文件使用的時候:
// 1.先導(dǎo)入組件,如:import {Header} from '../components/Header'
// 2.直接使用組件厢洞,如:Header({title: '商品列表'})
@Builder
自定義構(gòu)建函數(shù):是將代碼封裝成函數(shù)仇让,通過函數(shù)調(diào)用進(jìn)行使用。方便代碼復(fù)用躺翻,使代碼更加簡潔丧叽。
注意:
1》定義在組件外部的函數(shù)是全局函數(shù),因?yàn)楹瘮?shù)沒有在class/struct中公你,所以定義的時候需要function關(guān)鍵字踊淳,使用的時候直接調(diào)用即可。
函數(shù)定義格式:@Builder function ItemCard(item: Item) { ... }
函數(shù)調(diào)用格式:ItemCard(item)
2》定義在組件內(nèi)部的函數(shù)是局部函數(shù)陕靠,定義的時候不需要function關(guān)鍵字迂尝,使用的時候需要通過"this.函數(shù)名"進(jìn)行調(diào)用
函數(shù)定義格式:@Builder ItemCard2(item: Item) { ... }
函數(shù)調(diào)用格式:this.ItemCard2(item)
@Styles
擴(kuò)展組件公共樣式:和上面的自定義構(gòu)建函數(shù)一樣,將公共樣式/屬性方法封裝成函數(shù)剪芥,通過函數(shù)調(diào)用進(jìn)行使用垄开。
// 擴(kuò)展組件通用屬性(適用于所有組件)
// 調(diào)用和使用系統(tǒng)的屬性方法一樣,如:.fillScreen()
@Styles function fillScreen() {
// 注意點(diǎn):這里面寫的屬性必須是所有組件的通用屬性
.width('100%')
.height('100%')
.backgroundColor('#f1f1f1')
.padding(20)
// 如:字體大小屬性不是所有組件的通用屬性税肪,寫會報錯溉躲;為了解決這個問題,可以使用 @Extend 來擴(kuò)展指定組件的樣式
//.fontSize(18)
}
-
@Extend
擴(kuò)展特定組件樣式
// 擴(kuò)展組件特有屬性(僅可定義在全局)
@Extend(Text) function titleStyle(fontSize: number = 20) {
.fontSize(fontSize)
.fontColor('#333')
}