一、鴻蒙應(yīng)用開發(fā)-初體驗(yàn)
二眠砾、鴻蒙應(yīng)用開發(fā)-基礎(chǔ)組件
三、鴻蒙應(yīng)用開發(fā)-組件樣式
四托酸、鴻蒙應(yīng)用開發(fā)-組件構(gòu)建函數(shù)
五褒颈、鴻蒙應(yīng)用開發(fā)-組件組件狀態(tài)共享
六、鴻蒙應(yīng)用開發(fā)-應(yīng)用狀態(tài)存儲(chǔ)
目錄
樣式處理
1. 樣式-語法(鏈?zhǔn)?amp;枚舉)
ArkTS以聲明方式組合和擴(kuò)展組件來描述應(yīng)用程序的UI 同時(shí)還提供了基本的屬性励堡、事件和子組件配置方法谷丸,幫助開發(fā)者實(shí)現(xiàn)應(yīng)用交互邏輯。
1.樣式屬性
- 屬性方法以
.
鏈?zhǔn)秸{(diào)用的方式配置系統(tǒng)組件的樣式和其他屬性应结,建議每個(gè)屬性方法單獨(dú)寫一行刨疼。
@Entry
@Component
struct Index {
build() {
Text('演示')
.backgroundColor('red')
.fontSize(50)
.width('100%')
.height(100)
}
}
2.枚舉值
- 對(duì)于系統(tǒng)組件,ArkUI還為其屬性預(yù)定義了一些枚舉類型鹅龄。文檔鏈接
@Entry
@Component
struct Index {
build() {
Text('演示')
.fontSize(50)
.width('100%')
.height(100)
.backgroundColor(Color.Blue)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}
}
- 樣式相關(guān)屬性通過鏈?zhǔn)胶瘮?shù)的方式進(jìn)行設(shè)置
- 如果類型是枚舉的揩慕,通過枚舉傳入對(duì)應(yīng)的值
2. 樣式-單位 vp
和適配
-
vp
是什么?virtual pixel
- 屏幕密度相關(guān)像素扮休,根據(jù)屏幕像素密度轉(zhuǎn)換為屏幕物理像素迎卤,當(dāng)數(shù)值不帶單位時(shí),默認(rèn)單位
vp
玷坠;在實(shí)際寬度為1440物理像素的屏幕上蜗搔,1vp
約等于3px
(物理像素)
- 上圖的意思是劲藐,使用這個(gè)單位在不同屏幕物理分辨率的實(shí)際尺寸一致(A設(shè)備1英寸,B設(shè)備1英寸)樟凄。
2.之前 vw
瘩燥、rem
和 rpx
相對(duì)于屏幕寬度的單位,可以實(shí)現(xiàn)等比例適配不同,vp
可以嗎厉膀?
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct Index {
build() {
Text('演示')
.width('100%')
.backgroundColor('red')
.onAreaChange((oldArea, newArea) => {
promptAction.showToast({
// 1. onAreaChange改變尺寸后會(huì)觸發(fā)
// 2. newArea為現(xiàn)在元素尺寸
message: newArea.width.toString()
})
})
}
}
我們發(fā)現(xiàn):不同的設(shè)備屏幕的寬度 vp
是不一致的,那怎么適配呢二拐?
- 根據(jù)官方的文檔服鹅,結(jié)合自己的理解,采用:伸縮布局百新,網(wǎng)格系統(tǒng)企软,柵格系統(tǒng)進(jìn)行布局適配。
伸縮 layoutWeight(flex: number)
占剩余空間多少份饭望,可以理解成CSS的 flex: 1
@Entry
@Component
struct Index {
build() {
Row(){
Text('left')
.layoutWeight(1)
.backgroundColor('red')
Text('right')
.layoutWeight(2)
.backgroundColor('green')
}
.width('100%')
}
}
等比例仗哨,設(shè)置元素寬高比 aspectRatio(ratio: number)
@Entry
@Component
struct Index {
build() {
Text('left')
.width('50%')
// 寬高比例
.aspectRatio(1)
.backgroundColor('red')
}
}
-
vp
是鴻蒙默認(rèn)單位,和屏幕像素有關(guān)铅辞,最終表現(xiàn)視覺大小在任何設(shè)備一致 - 鴻蒙一般以伸縮
layoutWeight
厌漂、網(wǎng)格、柵格進(jìn)行布局適配斟珊,如要等比例縮放可以設(shè)置高寬比aspectRatio
?????? 案例→實(shí)現(xiàn)知乎評(píng)論回復(fù)-評(píng)論區(qū)域
設(shè)計(jì)稿一般是1080px:(這里沒有設(shè)計(jì)稿苇倡,提供了一些尺寸)
- Nav
- 左側(cè)返回按鈕
24vp
高寬背景顏色#f5f5f5
,圖標(biāo)12vp尺寸顏色#848484
- 標(biāo)題
18vp
- 左側(cè)返回按鈕
- Comment
- 頭像尺寸32vp高寬囤踩,右側(cè)間距10vp
- 標(biāo)題15vp旨椒,顏色默認(rèn)
- 內(nèi)容16vp,顏色
#565656
- 底部12vp堵漱,顏色
#c3c4c5
@Entry
@Component
struct Index {
build() {
Column(){
// 導(dǎo)航
Row(){
Row(){
Image($r('app.media.ic_public_arrow_left'))
.width(16)
.aspectRatio(1)
// svg 圖標(biāo)可以使用填充顏色
// .fillColor('red')
}
.width(24)
.aspectRatio(1)
.backgroundColor('#f5f5f5')
.borderRadius(12)
.justifyContent(FlexAlign.Center)
.margin({ left: 16 })
Text('評(píng)論回復(fù)')
.layoutWeight(1)
.textAlign(TextAlign.Center)
.padding({ right: 40 })
}
.height(40)
.border({ width: { bottom: 0.5 }, color: '#e4e4e4' })
// 評(píng)論
Row(){
Image($r('app.media.avatar'))
.width(32)
.aspectRatio(1)
.borderRadius(16)
Column({ space: 5 }){
Text('周杰倫')
.width('100%')
.fontWeight(FontWeight.Bold)
.fontSize(15)
Text('大理石能雕刻出肌肉和皮膚的質(zhì)感综慎,那個(gè)年代的工匠好牛啊')
.width('100%')
Row(){
Text('10-21 · IP屬地北京')
.fontSize(12)
.fontColor('#c3c4c5')
Row({ space: 4 }){
Image($r('app.media.ic_public_heart'))
.width(14)
.aspectRatio(1)
.fillColor('#c3c4c5')
Text('100')
.fontSize(12)
.fontColor('#c3c4c5')
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.layoutWeight(1)
.padding({ left: 10 })
}
.padding(15)
.alignItems(VerticalAlign.Top)
}
}
}
- 華為官方圖標(biāo)下載 鏈接
樣式-@Styles 復(fù)用
在開發(fā)過程中會(huì)出現(xiàn)大量代碼在進(jìn)行重復(fù)樣式設(shè)置,@Styles 可以幫我們進(jìn)行樣式復(fù)用
// 全局
@Styles
function functionName() { ... }
@Entry
@Component
sturt Index{
// 組件內(nèi)
@Styles
functionName() { ... }
build() {
Text('Text')
.functionName()
}
}
案例:文字和按鈕相同背景埃元,點(diǎn)擊+1
- 全局
@Styles function sameStyle() {
.backgroundColor(Color.Green)
.onClick(() => {
this.count++
})
}
@Entry
@Component
struct Index {
@State
count: number = 10
build() {
Column() {
Text(this.count.toString())
.width(100)
.height(50)
.margin({ bottom: 10 })
.textAlign(TextAlign.Center)
.sameStyle()
Button('+1')
.sameStyle()
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
- 組件內(nèi)
@Entry
@Component
struct Index {
@State
count: number = 10
// 不需要 `function` 關(guān)鍵字涝涤,覆蓋全局
@Styles
sameStyle (){
.backgroundColor(Color.Pink)
.onClick(() => {
this.count += 10
})
}
build() {
Column() {
Text(this.count.toString())
.width(100)
.height(50)
.margin({ bottom: 10 })
.textAlign(TextAlign.Center)
.sameStyle()
Button('+1')
.sameStyle()
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
?????? 練習(xí)案例-登錄表單-樣式優(yōu)化
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct Index {
@State
mobile: string = ''
@State
code: string = ''
@Styles
inputStyle () {
.border({ width: 1, color: Color.Gray })
.layoutWeight(1)
.margin({ left: 10, bottom: 10, top: 10 })
.backgroundColor(Color.White)
}
build() {
Column(){
Row(){
Text('手機(jī)號(hào)')
TextInput({ text: this.mobile })
.inputStyle()
.onChange((value)=>this.mobile = value)
}
Row(){
Text('驗(yàn)證碼')
TextInput({ text: this.code })
.inputStyle()
.onChange((value)=>this.code = value)
}
Row({ space: 15 }){
Button('重置')
.backgroundColor('#ccc')
.onClick(()=>{
this.mobile = ''
this.code = ''
})
Button('登錄')
.onClick(()=>{
if (this.mobile && this.code) {
promptAction.showToast({ message: `${this.mobile} 登錄成功` })
} else {
promptAction.showToast({ message: `請(qǐng)輸入手機(jī)號(hào)或驗(yàn)證碼` })
}
})
}
}
.padding({ left: 15, right: 15 })
}
}
樣式-@Extends 復(fù)用
@Extend 用于擴(kuò)展原生組件樣式媚狰,通過傳參提供更靈活的樣式復(fù)用
- 使用
@Extend
裝飾器修飾的函數(shù)只能是全局
- 函數(shù)可以進(jìn)行
傳參
岛杀,如果參數(shù)是狀態(tài)變量,狀態(tài)更新后會(huì)刷新UI - 且參數(shù)可以是一個(gè)函數(shù)崭孤,實(shí)現(xiàn)復(fù)用事件且可處理不同邏輯
// 全局 原生組件 參數(shù)
// ↓ ↓ ↓
@Extend(Text) function functionName(w: number) {
.width(w)
}
需求:把 Text 改成按鈕樣式类嗤,且綁定 click 事件執(zhí)行不同邏輯
import promptAction from '@ohos.promptAction'
@Extend(Text) function myClick(color: string, cb: () => void) {
.backgroundColor(color)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
.borderRadius(25)
.onClick(() => cb())
}
@Entry
@Component
struct Other {
@State
color: string = '#ccc'
build() {
Column({ space: 20 }) {
Text('Text1')
.myClick(this.color, () => {
this.color = '#069'
})
Text('Text2')
.myClick('green', () => {
promptAction.showToast({ message: '做其他事~' })
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
樣式-多態(tài)
stateStyles
是屬性方法糊肠,可以根據(jù)UI內(nèi)部狀態(tài)來設(shè)置樣式,類似于 css 偽類遗锣,但語法不同货裹。ArkUI 提供以下四種狀態(tài):
focused:獲焦態(tài)。
normal:正常態(tài)精偿。
pressed:按壓態(tài)弧圆。
disabled:不可用態(tài)。
import promptAction from '@ohos.promptAction'
// 膠囊按鈕
@Extend(Text)
function capsule(){
.height(40)
.borderRadius(20)
.backgroundColor(Color.Gray)
.padding({ left: 15, right: 15 })
.margin({ bottom: 15 })
}
@Entry
@Component
struct Index {
@State
disabled: boolean = false
@State
focused: boolean = false
build() {
Column() {
// Button TextInput 默認(rèn)開啟獲取焦點(diǎn)笔咽,頁面中默認(rèn)第一個(gè)這樣的元素獲取焦點(diǎn)
// Button 比較多限制搔预,一個(gè)是默認(rèn)開啟獲取焦點(diǎn)能看,二是禁用狀態(tài)下樣式無法修改
// Button('Button').focusable(false)
Text('toggle disabled:' + this.disabled)
.capsule()
.onClick(()=>{
this.disabled = !this.disabled
})
Text('toggle focused:' + this.focused)
.capsule()
.onClick(()=>{
this.focused = !this.focused
})
Text('clickMe')
.capsule()
.enabled(!this.disabled)
.focusable(this.focused)
.onClick(() => {
promptAction.showToast({ message: 'click' })
})
.fontColor('#fff')
.stateStyles({
normal: {
.backgroundColor(Color.Blue)
},
focused: {
.backgroundColor(Color.Red)
},
disabled: {
.backgroundColor(Color.Black)
},
pressed: {
.backgroundColor(Color.Orange)
}
})
}
}
}
- 使用比較多的應(yīng)該是
norma
pressed
結(jié)合下的按壓效果 -
enabled(true|false)
開啟|禁用focusable(true|false)
開啟獲取焦點(diǎn)能力|關(guān)閉
注意:
- 頁面初始化的時(shí)候叶组,默認(rèn)第一個(gè)能獲取焦點(diǎn)的元素拯田,會(huì)自動(dòng)獲取焦點(diǎn)