0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙ArkUI開發(fā)學(xué)習(xí):【渲染控制語法】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-09 16:40 ? 次閱讀

ArkUI開發(fā)框架是一套構(gòu)建 HarmonyOS / OpenHarmony 應(yīng)用界面的聲明式UI開發(fā)框架,它支持程序使用 if/else 條件渲染, ForEach 循環(huán)渲染以及 LazyForEach 懶加載渲染。本節(jié)筆者介紹一下這三種渲染方式的使用。

if/else條件渲染

使用 if/else 進(jìn)行條件渲染需要注意以下情況:

  • if 條件語句可以使用狀態(tài)變量。

  • 使用 if 可以使子組件的渲染依賴條件語句。

  • 必須在容器組件內(nèi)使用。

  • 某些容器組件限制子組件的類型或數(shù)量。將if放置在這些組件內(nèi)時(shí),這些限制將應(yīng)用于 ifelse 語句內(nèi)創(chuàng)建的組件。例如,Grid 組件的子組件僅支持 GridItem 組件,在 Grid 組件內(nèi)使用條件渲染時(shí),則 if 條件語句內(nèi)僅允許使用 GridItem 組件。
    簡單樣例如下所示:

    @Entry @Component struct ComponentTest {
    
      @State showImage: boolean = false;
    
      build() {
        Column({space: 10}) {
    
          if (this.showImage) {            // 顯示圖片
            Image($r("app.media.test"))
              .width(160)
              .height(60)
              .backgroundColor(Color.Pink)
          } else {                         // 顯示文本
            Text('Loading...')
              .fontSize(23)
              .width(160)
              .height(60)
              .backgroundColor(Color.Pink)
          }
    
          Button(this.showImage ? 'Image Loaded' : 'Load Image')    // 按鈕文字
            .size({width: 160, height: 40})
            .backgroundColor(this.showImage ? Color.Gray : '#aabbcc')// 按鈕背景色
            .onClick(() = > {
              this.showImage = true;                                 // 設(shè)置標(biāo)記位
            })
        }
        .width('100%')
        .height('100%')
        .padding(10)
      }
    }
    

    樣例運(yùn)行結(jié)果如下圖所示:

    2_4_1

ForEach循環(huán)渲染

ArkUI開發(fā)框架提供循環(huán)渲染(ForEach組件)來迭代數(shù)組,并為每個(gè)數(shù)組項(xiàng)創(chuàng)建相應(yīng)的組件。

ForEach 定義如下:

interface ForEach {(
	arr: Array< any >, 
	itemGenerator: (item: any, index?: number) = > void,
  keyGenerator?: (item: any, index?: number) = > string
  ): ForEach;
}
  • arr :必須是數(shù)組,允許空數(shù)組,空數(shù)組場景下不會(huì)創(chuàng)建子組件。
  • itemGenerator :子組件生成函數(shù),為給定數(shù)組項(xiàng)生成一個(gè)或多個(gè)子組件。
  • keyGenerator :匿名參數(shù),用于給定數(shù)組項(xiàng)生成唯一且穩(wěn)定的鍵值。
    簡單樣例如下所示:
@Entry @Component struct ComponentTest {

  private textArray: string[] = ["1", "2", "3", "4", "5"];        // 數(shù)據(jù)源

  build() {
    Column({space: 10}) {
      ForEach(this.textArray, (item: string, index?: number) = > { // 循環(huán)數(shù)組創(chuàng)建每一個(gè)Item
        Text(`Text: ${item}`)                                     // 可以生成一個(gè)或多個(gè)子組件
          .fontSize(20)
          .backgroundColor(Color.Pink)
          .margin({ top: 10 })
      })
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }
}

樣例運(yùn)行結(jié)果如下圖所示:

2_4_2

LazyForEach循環(huán)渲染

搜狗高速瀏覽器截圖20240326151547.png

ArkUI開發(fā)框架提供數(shù)據(jù)懶加載( LazyForEach 組件)從提供的數(shù)據(jù)源中按需迭代數(shù)據(jù),并在每次迭代過程中創(chuàng)建相應(yīng)的組件。

  1. LazyForEach 定義如下:

    // LazyForEach定義
    interface LazyForEach {(
    	dataSource: IDataSource, 
      itemGenerator: (item: any, index?: number) = > void,
      keyGenerator?: (item: any, index?: number) = > string
      ): LazyForEach;
    }
    
    // IDataSource定義
    export declare interface IDataSource {
      totalCount(): number;
      getData(index: number): any;
      registerDataChangeListener(listener: DataChangeListener): void;
      unregisterDataChangeListener(listener: DataChangeListener): void;
    }
    
    // DataChangeListener定義
    export declare interface DataChangeListener {
      onDataReloaded(): void;
      onDataAdded(index: number): void;
      onDataMoved(from: number, to: number): void;
      onDataDeleted(index:number): void;
      onDataChanged(index:number): void;
    }
    
    • itemGenerator :子組件生成函數(shù),為給定數(shù)組項(xiàng)生成一個(gè)或多個(gè)子組件。
    • keyGenerator :匿名參數(shù),用于給定數(shù)組項(xiàng)生成唯一且穩(wěn)定的鍵值。
    • dataSource :實(shí)現(xiàn) IDataSource 接口的對象,需要開發(fā)者實(shí)現(xiàn)相關(guān)接口。
  2. IDataSource 定義如下:

    export declare interface IDataSource {
      totalCount(): number;
      getData(index: number): any;
      registerDataChangeListener(listener: DataChangeListener): void;
      unregisterDataChangeListener(listener: DataChangeListener): void;
    }
    
    • totalCount :獲取數(shù)據(jù)總數(shù)。
    • getData :獲取索引對應(yīng)的數(shù)據(jù)。
    • registerDataChangeListener :注冊改變數(shù)據(jù)的監(jiān)聽器。
    • unregisterDataChangeListener :注銷改變數(shù)據(jù)的監(jiān)聽器。
  3. DataChangeListener 定義如下:

    export declare interface DataChangeListener {
      onDataReloaded(): void;
      onDataAdded(index: number): void;
      onDataMoved(from: number, to: number): void;
      onDataDeleted(index:number): void;
      onDataChanged(index:number): void;
    }
    
    • onDataReloaded :item重新加載數(shù)據(jù)時(shí)的回調(diào)。
    • onDataAdded :item新添加數(shù)據(jù)時(shí)的回調(diào)。
    • onDataMoved :item數(shù)據(jù)移動(dòng)時(shí)的回調(diào)。
    • onDataDeleted :item數(shù)據(jù)刪除時(shí)的回調(diào)。
    • onDataChanged :item數(shù)據(jù)變化時(shí)的回調(diào)。

簡單樣例如下:

// 定義Student
class Student {
  public sid: number;
  public name: string;
  public age: number
  public address: string
  public avatar: string
  constructor(sid: number = -1, name: string, age: number = 16, address: string = '北京', avatar: string = "") {
    this.sid = sid;
    this.name = name;
    this.age = age;
    this.address = address;
    this.avatar = avatar;
  }
}

// 定義DataSource
abstract class BaseDataSource< T > implements IDataSource {

  private mDataSource: T[] = new Array();

  constructor(dataList: T[]) {
    this.mDataSource = dataList;
  }

  totalCount(): number {
    return this.mDataSource == null ? 0 : this.mDataSource.length
  }

  getData(index: number): T|null {
    return index >= 0 && index < this.totalCount() ? this.mDataSource[index] : null;
  }

  registerDataChangeListener(listener: DataChangeListener) {
  }

  unregisterDataChangeListener(listener: DataChangeListener) {
  }

}

// 
class StudentDataSource extends BaseDataSource< Student > {
  constructor(students: Student[]) {
    super(students)
  }
}

function mock(): Student[] {
  var students = [];
  for(var i = 0; i < 20; i++) {
    students[i] = new Student(i, "student:" + i, i + 10, "address:" + i, "app.media.test")
  }
  return students;
}

@Entry @Component struct ComponentTest {

  // mock數(shù)據(jù)
  private student: Student[] = mock();

  // 創(chuàng)建dataSource
  private dataSource: StudentDataSource = new StudentDataSource(this.student);

  build() {
    Column({space: 10}) {
      List() {
        LazyForEach(this.dataSource, (item: Student) = > {// LazyForEach使用自定義dataSource
          ListItem() {
            Row() {
              Image($r("app.media.test"))
                .height('100%')
                .width(80)
              Column() {
                Text(this.getName(item)) // 調(diào)用getName驗(yàn)證懶加載
                  .fontSize(20)
                Text('address: ' + item.address)
                  .fontSize(17)
              }
              .margin({left: 5})
              .alignItems(HorizontalAlign.Start)
              .layoutWeight(1)
            }
            .width('100%')
            .height('100%')
          }
          .width('100%')
          .height(60)
        })
      }
      .divider({
        strokeWidth: 3,
        color: Color.Gray
      })
      .width('90%')
      .height(160)
      .backgroundColor(Color.Pink)
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }

  getName(item: Student): string {
    console.log("index: " + item.sid); // 打印item下標(biāo)日志
    return 'index:' + item.sid + ", " + item.name;
  }
}

樣例運(yùn)行結(jié)果如下圖所示:

2_4_3

打印結(jié)果如下:

[phone][Console    INFO]  04/02 23:54:19 82919424 app Log: Application onCreate
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 0
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 1
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 2
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 3
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 4
[phone][Console   DEBUG]  04/02 23:54:19 82919424 app Log: index: 5

使用懶加載,可以有效的降低資源占用

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2302

    瀏覽量

    42689
  • HarmonyOS
    +關(guān)注

    關(guān)注

    79

    文章

    1966

    瀏覽量

    29962
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3635

    瀏覽量

    16061
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    鴻蒙ArkUI開發(fā)-Video組件的使用

    以視頻功能為例,在應(yīng)用開發(fā)過程中,我們需要通過ArkUI提供的Video組件為應(yīng)用增加基礎(chǔ)的視頻播放功能。借助Video組件,我們可以實(shí)現(xiàn)視頻的播放功能并控制其播放狀態(tài)。常見的視頻播放場景包括觀看網(wǎng)絡(luò)上的較為流行的短視頻,也包括
    的頭像 發(fā)表于 01-23 16:59 ?1210次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>ArkUI</b><b class='flag-5'>開發(fā)</b>-Video組件的使用

    鴻蒙開發(fā)學(xué)習(xí):初探【ArkUI-X】

    **簡單來說,ArkTS + ArkUI-X 對標(biāo)的框架為 flutter,一次代碼,編譯為 native 全平臺(tái)運(yùn)行**
    的頭像 發(fā)表于 05-13 15:58 ?958次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>學(xué)習(xí)</b>:初探【<b class='flag-5'>ArkUI</b>-X】

    免費(fèi)學(xué)習(xí)鴻蒙(HarmonyOS)開發(fā),一些地址分享

    國內(nèi)一流高校。通過鴻蒙班的設(shè)立,高??梢詾閷W(xué)生提供專業(yè)的鴻蒙OS學(xué)習(xí)環(huán)境和豐富的實(shí)踐機(jī)會(huì),培養(yǎng)出更多的鴻蒙開發(fā)人才,為
    發(fā)表于 01-12 20:48

    HarmonyOS實(shí)戰(zhàn)開發(fā)-合理選擇條件渲染和顯隱控制

    14ms。 可見,針對反復(fù)切換條件渲染控制分支的情況,且控制分支中的組件子樹結(jié)構(gòu)比較復(fù)雜,使用組件復(fù)用機(jī)制,可以提升應(yīng)用性能。 最后 如果大家覺得這篇內(nèi)容對學(xué)習(xí)
    發(fā)表于 05-10 15:16

    請問鴻蒙系統(tǒng)是否支持native側(cè)opengles渲染引擎開發(fā)?

    鴻蒙系統(tǒng)是否支持native側(cè)opengles渲染引擎開發(fā)
    發(fā)表于 05-27 15:11

    HDD杭州站?ArkUI開發(fā)更靈活

    。 采用聲明式語法,更符合開發(fā)者繪制習(xí)慣。 框架集成Canvas能力,無需引入Web引擎。 同時(shí),ArkUI還提供離屏繪制能力。當(dāng)繪制的圖形比較復(fù)雜時(shí),頻繁的刪除與重繪會(huì)消耗很多性能。這時(shí),
    發(fā)表于 08-05 11:33

    ArkUI,更高效的框架設(shè)計(jì)

    ArkUI是一套用于構(gòu)建HarmonyOS應(yīng)用界面的UI開發(fā)框架,本期我們將從架構(gòu)設(shè)計(jì)上來聊聊ArkUI的設(shè)計(jì)理念。 ArkUI架構(gòu)圖 從架構(gòu)圖可以看出,
    發(fā)表于 12-21 10:26

    4天帶你上手HarmonyOS ArkUI開發(fā)——《HarmonyOS ArkUI入門訓(xùn)練營之健康生活實(shí)戰(zhàn)》

    者快速提升技能實(shí)力進(jìn)階。目標(biāo)學(xué)員入門開發(fā)者(計(jì)算機(jī)專業(yè)相關(guān))學(xué)習(xí)鏈接:https://t.elecfans.com/c2241.html訓(xùn)練營目標(biāo)通過學(xué)習(xí)ArkUI入門訓(xùn)練營課程,了解
    發(fā)表于 01-05 11:49

    ArkUI新能力,助力應(yīng)用開發(fā)更便捷

    ArkUI是一套構(gòu)建分布式應(yīng)用的聲明式UI開發(fā)框架。它具備簡潔自然的UI信息語法、豐富的UI組件、多維的狀態(tài)管理,以及實(shí)時(shí)界面預(yù)覽等相關(guān)能力,幫助您提升應(yīng)用開發(fā)效率,并能在多種設(shè)備上實(shí)
    發(fā)表于 02-15 11:40

    HarmonyOS/OpenHarmony應(yīng)用開發(fā)-ArkTS語言渲染控制概述

    ArkUI通過自定義組件的build()函數(shù)和@builder裝飾器中的聲明式UI描述語句構(gòu)建相應(yīng)的UI。 在聲明式描述語句中開發(fā)者除了使用系統(tǒng)組件外,還可以使用渲染控制語句來輔助U
    發(fā)表于 08-09 09:54

    ArkUI新能力,助力應(yīng)用開發(fā)更便捷

    作者:niulihua,華為ArkUI技術(shù)專家;wanglei,華為ArkUI技術(shù)專家 ArkUI是一套構(gòu)建分布式應(yīng)用的聲明式UI開發(fā)框架。它具備簡潔自然的UI信息
    的頭像 發(fā)表于 02-15 16:35 ?835次閱讀

    鴻蒙ArkUI開發(fā)-Tabs組件的使用

    鴻蒙ArkUI開發(fā)-Tabs組件的使用
    的頭像 發(fā)表于 01-19 16:01 ?1704次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>ArkUI</b><b class='flag-5'>開發(fā)</b>-Tabs組件的使用

    鴻蒙ArkUI實(shí)例:【自定義組件】

    組件是 OpenHarmony 頁面最小顯示單元,一個(gè)頁面可由多個(gè)組件組合而成,也可只由一個(gè)組件組合而成,這些組件可以是ArkUI開發(fā)框架自帶系統(tǒng)組件,比如?`Text`?、?`Button`?等,也可以是自定義組件,本節(jié)筆者簡單介紹一下自定義組件的
    的頭像 發(fā)表于 04-08 10:17 ?581次閱讀

    鴻蒙ArkUI:【從代碼到UI顯示的整體渲染流程】

    方舟開發(fā)框架(簡稱ArkUI)是鴻蒙開發(fā)的UI框架,提供如下兩種開發(fā)范式,我們 **只學(xué)聲明式開發(fā)
    的頭像 發(fā)表于 05-13 16:06 ?770次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>ArkUI</b>:【從代碼到UI顯示的整體<b class='flag-5'>渲染</b>流程】

    鴻蒙ArkUI-X跨平臺(tái)技術(shù):【開發(fā)準(zhǔn)備】

    本文檔適用于ArkUI跨平臺(tái)應(yīng)用開發(fā)的初學(xué)者。通過開發(fā)環(huán)境搭建、應(yīng)用工程創(chuàng)建、編譯和運(yùn)行,熟悉ArkUI跨平臺(tái)應(yīng)用開發(fā)基本流程。
    的頭像 發(fā)表于 05-24 10:40 ?411次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>ArkUI</b>-X跨平臺(tái)技術(shù):【<b class='flag-5'>開發(fā)</b>準(zhǔn)備】