鴻蒙應(yīng)用開發(fā)-組件樣式

一、鴻蒙應(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 和適配
  1. vp 是什么?virtual pixel
  • 屏幕密度相關(guān)像素扮休,根據(jù)屏幕像素密度轉(zhuǎn)換為屏幕物理像素迎卤,當(dāng)數(shù)值不帶單位時(shí),默認(rèn)單位 vp玷坠;在實(shí)際寬度為1440物理像素的屏幕上蜗搔,1vp 約等于 3px(物理像素)
    image.png
  • 上圖的意思是劲藐,使用這個(gè)單位在不同屏幕物理分辨率的實(shí)際尺寸一致(A設(shè)備1英寸,B設(shè)備1英寸)樟凄。

2.之前 vw 瘩燥、remrpx 相對(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 是不一致的,那怎么適配呢二拐?

  1. 根據(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ū)域
1.jpeg

設(shè)計(jì)稿一般是1080px:(這里沒有設(shè)計(jì)稿苇倡,提供了一些尺寸)

  • Nav
    • 左側(cè)返回按鈕24vp高寬背景顏色#f5f5f5,圖標(biāo)12vp尺寸顏色#848484
    • 標(biāo)題18vp
  • 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ù)用

  • 當(dāng)前 @Styles 僅支持 通用屬性通用事件勤庐。
  • 支持 全局 定義和 組件內(nèi) 定義示惊,同時(shí)存在組件內(nèi)覆蓋全局生效。
// 全局
@Styles 
function functionName() { ... }

@Entry
@Component
sturt Index{
  // 組件內(nèi)
  @Styles 
  functionName() { ... }

  build() {
    Text('Text')
      .functionName()
  }
}

案例:文字和按鈕相同背景埃元,點(diǎn)擊+1

2.jpeg
  • 全局
@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)化


4.jpeg
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í)行不同邏輯

WechatIMG25.jpeg

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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市甩十,隨后出現(xiàn)的幾起案子船庇,更是在濱河造成了極大的恐慌,老刑警劉巖侣监,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸭轮,死亡現(xiàn)場離奇詭異,居然都是意外死亡橄霉,警方通過查閱死者的電腦和手機(jī)张弛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酪劫,“玉大人吞鸭,你說我怎么就攤上這事「苍悖” “怎么了刻剥?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滩字。 經(jīng)常有香客問我造虏,道長,這世上最難降的妖魔是什么麦箍? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任漓藕,我火速辦了婚禮,結(jié)果婚禮上挟裂,老公的妹妹穿的比我還像新娘享钞。我一直安慰自己,他們只是感情好诀蓉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布栗竖。 她就那樣靜靜地躺著暑脆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狐肢。 梳的紋絲不亂的頭發(fā)上添吗,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音份名,去河邊找鬼碟联。 笑死,一個(gè)胖子當(dāng)著我的面吹牛僵腺,可吹牛的內(nèi)容都是我干的玄帕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼想邦,長吁一口氣:“原來是場噩夢啊……” “哼裤纹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丧没,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤鹰椒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后呕童,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漆际,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年夺饲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奸汇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡往声,死狀恐怖擂找,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浩销,我是刑警寧澤贯涎,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站慢洋,受9級(jí)特大地震影響塘雳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜普筹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一败明、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧太防,春花似錦妻顶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至醇王,卻和暖如春呢燥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寓娩。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工叛氨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棘伴。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓寞埠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焊夸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仁连,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容