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

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

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

harmonyos開發(fā)者平臺

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-05-06 16:02 ? 次閱讀

介紹

使用@State、@Prop、@Link、@Watch、@Provide、@Consume管理頁面級變量的狀態(tài),實現(xiàn)對頁面數(shù)據(jù)的增加、刪除、修改。要求完成以下功能:

  1. 實現(xiàn)一個自定義彈窗,完成添加子目標的功能。
  2. 實現(xiàn)一個可編輯列表,可點擊指定行展開調(diào)節(jié)工作目標進度,可多選、全選刪除指定行。

相關(guān)概念

  • [頁面狀態(tài)管理]:用于管理頁面級變量的狀態(tài)。
  • [自定義彈窗]: 通過CustomDialogController類顯示自定義彈窗。
  • [List列表]:列表包含一系列相同寬度的列表項。

環(huán)境搭建

軟件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 開發(fā)板類型:[潤和RK3568開發(fā)板]。
  • OpenHarmony系統(tǒng):3.2 Release。

環(huán)境搭建

完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:

  1. [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
  2. 搭建燒錄環(huán)境。
    1. [完成DevEco Device Tool的安裝]
    2. [完成RK3568開發(fā)板的燒錄]
  3. 搭建開發(fā)環(huán)境。
    1. 開始前請參考[工具準備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
    2. 開發(fā)環(huán)境配置完成后,請參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”)。
    3. 工程創(chuàng)建完成后,選擇使用[真機進行調(diào)測]。
    4. 鴻蒙開發(fā)指導(dǎo)文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

代碼結(jié)構(gòu)解讀

本篇Codelab只對核心代碼進行講解,對于完整代碼,我們會在gitee中提供。

├──entry/src/main/ets                   // ArkTS代碼區(qū)
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets         // 公共常量類
│  │  └──utils
│  │     ├──DateUtil.ets                // 獲取格式化日期工具
│  │     └──Logger.ets                  // 日志打印工具類
│  ├──entryability
│  │  └──EntryAbility.ts                // 程序入口類
│  ├──pages
│  │  └──MainPage.ets                   // 主頁面
│  ├──view
│  │  ├──TargetInformation.ets          // 整體目標詳情自定義組件
│  │  ├──AddTargetDialog.ets            // 自定義彈窗
│  │  ├──ProgressEditPanel.ets          // 進展調(diào)節(jié)自定義組件
│  │  ├──TargetList.ets                 // 工作目標列表
│  │  └──TargetListItem.ets             // 工作目標列表子項
│  └──viewmodel
│     ├──DataModel.ets                  // 工作目標數(shù)據(jù)操作類
│     └──TaskItemViewModel.ets          // 任務(wù)進展實體類
└──entry/src/main/resources             // 資源文件目錄

`HarmonyOSOpenHarmony鴻蒙文檔籽料:mau123789v直接拿`

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

構(gòu)建主界面

MainPage作為本應(yīng)用的主界面,從上至下由三個自定義組件組成。

  1. 標題titleBar。
  2. 目標整體進展詳情TargetInformation。
  3. 子目標列表TargetList。

MainPage主要維護五個參數(shù):子目標數(shù)組targetData、子目標總數(shù)totalTasksNumber、已完成子目標數(shù)completedTasksNumber、最近更新時間latestUpdateDate、監(jiān)聽數(shù)據(jù)變化的參數(shù)overAllProgressChanged。具體作用有以下三個方面:

  1. 子組件TargetInformation接收三個參數(shù)totalTasksNumber、completedTasksNumber、latestUpdateDate,渲染整體目標詳情。
  2. 子組件TargetList接收參數(shù)targetData渲染列表。
  3. 使用@Watch監(jiān)聽overAllProgressChanged的變化。當(dāng)overAllProgressChanged改變時,回調(diào)onProgressChanged方法,刷新整體進展TargetInformation。
// MainPage.ets
@Entry
@Component
struct MainPage {
  // 子目標數(shù)組
  @State targetData: Array< TaskItemViewModel > = DataModel.getData();
  // 子目標總數(shù)
  @State totalTasksNumber: number = 0;
  // 已完成子目標數(shù)
  @State completedTasksNumber: number = 0;
  // 最近更新時間
  @State latestUpdateDate: string = CommonConstants.DEFAULT_PROGRESS_VALUE;
  // 監(jiān)聽數(shù)據(jù)變化的參數(shù)
  @Provide @Watch('onProgressChanged') overAllProgressChanged: boolean = false;	
  ...

  /**
   * overAllProgressChanged改變時的回調(diào)
   */
  onProgressChanged() {
    this.totalTasksNumber = this.targetData.length;
    this.completedTasksNumber = this.targetData.filter((item) = > {
      return item.progressValue === CommonConstants.SLIDER_MAX_VALUE;
    }).length;
    this.latestUpdateDate = getCurrentTime();
  }

  build() {
    Column() {
      // 標題
      this.titleBar()
      // 目標整體進展詳情
      TargetInformation({
        latestUpdateDate: this.latestUpdateDate,
        totalTasksNumber: this.totalTasksNumber,
        completedTasksNumber: this.completedTasksNumber
      })
      // 子目標列表
      TargetList({
        targetData: $targetData,
        onAddClick: () :void  = > this.dialogController.open()
      })
        ...
    }
    ...
  }

  @Builder
  titleBar() {
    Text($r('app.string.title'))
      ...
  }
}

添加任務(wù)子目標

本章節(jié)主要介紹如何實現(xiàn)一個自定義彈窗,完成添加子目標的功能。效果如圖所示:

在MainPage.ets中,創(chuàng)建dialogController對象控制彈窗隱顯,傳入自定義組件AddTargetDialog和點擊確定的回調(diào)方法saveTask。

// MainPage.ets
@Entry
@Component
struct MainPage {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: AddTargetDialog({
      onClickOk: (value: string): void = > this.saveTask(value)
    }),
    alignment: DialogAlignment.Bottom,
    offset: {
      dx: CommonConstants.DIALOG_OFFSET_X,
      dy: $r('app.float.dialog_offset_y')
    },
    customStyle: true,
    autoCancel: false
  });
}

在AddTargetDialog.ets中,參數(shù)onClickOk為function類型,接收MainPage傳入的saveTask方法。點擊確定,調(diào)用onClickOk執(zhí)行saveTask方法,關(guān)閉彈窗。

// AddTargetDialog .ets
@CustomDialog
export default struct AddTargetDialog {
  ...
  private controller?: CustomDialogController;
  onClickOk?: (value: string) = > void;

  build() {
    Column() {
      ...
      Text($r('app.string.add_task_dialog'))
      ...
      TextInput({ placeholder: $r('app.string.input_target_name')})
      ...
      .onChange((value: string) = > {
        this.subtaskName = value;
      })
      Blank()
      Row() {
        ...
        Button($r('app.string.confirm_button'))
          .dialogButtonStyle()
          .onClick(() = > {
            if (this.onClickOk !== undefined) {
              this.onClickOk(this.subtaskName);
            }
          })
      }
      ...
    }
    ...
  }
}

在MainPage.ets中,實現(xiàn)saveTask方法:保存數(shù)據(jù)至DataModel中,并更新targetData的值,完成添加子目標功能。

// MainPage.ets
saveTask(taskName: string) {
  if (taskName === '') {
    promptAction.showToast({
      message: $r('app.string.cannot_input_empty'),
      duration: CommonConstants.TOAST_TIME,
      bottom: CommonConstants.TOAST_MARGIN_BOTTOM
    });
    return;
  }
  DataModel.addData(new TaskItemViewModel(taskName, 0, getCurrentTime()));
  this.targetData = DataModel.getData();
  this.overAllProgressChanged = !this.overAllProgressChanged;
  this.dialogController.close();
}

實現(xiàn)可編輯列表

本章節(jié)主要介紹子目標列表TargetList的實現(xiàn),包括以下功能:

  • 列表項展開。
  • 列表子項點擊下拉,滑動滑塊更新進展。
  • 列表進入編輯狀態(tài),單選、多選、全選、刪除子項。

實現(xiàn)列表項展開

實現(xiàn)以下步驟完成點擊列表項展開功能:

  1. 使用@State 管理參數(shù)isExpanded,表示當(dāng)前項是否展開,具體表現(xiàn)為自定義組件ProgressEditPanel的顯示或隱藏。
  2. 使用@Link和@Watch管理參數(shù)clickIndex,表示當(dāng)前點擊ListItem的Index索引。clickIndex值的改變將會傳遞至所有的ListItem。
  3. 完成onClick點擊事件,將isExpanded 值置反,修改clickIndex值為當(dāng)前點擊的索引。
// TargetListItem.ets
@Component
export default struct TargetListItem {
  @State latestProgress?: number = 0;
  @Link @Watch('onClickIndexChanged') clickIndex: number;
  @State isExpanded: boolean = false;
  ...
  // clickIndex改變的回調(diào)方法
  onClickIndexChanged() {
    if (this.clickIndex !== this.index) {
      this.isExpanded = false;
    }
}

  build() {
    ...
    Column() {
      this.TargetItem()
      if (this.isExpanded) {
        Blank()
        // 自定義組件:編輯面板
        ProgressEditPanel({
          slidingProgress: this.latestProgress,
          onCancel: () = > this.isExpanded = false,
          onClickOK: (progress: number): void = > {
              this.latestProgress = progress;
              this.updateDate = getCurrentTime();
              let result = DataModel.updateProgress(this.index, this.latestProgress, this.updateDate);
              if (result) {
                this.overAllProgressChanged = !this.overAllProgressChanged;
              }
              this.isExpanded = false;
            },
          sliderMode: $sliderMode
        })
        ...
      }  
    }
    ...
    .onClick(() = > {
      ...
      if (!this.isEditMode) {
        animateTo({ duration: CommonConstants.DURATION }, () = > {
          this.isExpanded = !this.isExpanded;
        })
        this.clickIndex = this.index;
      }
    })
  }
  ...
}

實現(xiàn)更新進展

列表某項被展開后,實現(xiàn)以下步驟完成更新進展功能:

  1. Slider實現(xiàn)滑動條,滑動滑塊調(diào)節(jié)進展,使用slidingProgress保存滑動值。
  2. 點擊確定調(diào)用onClickOK方法,將數(shù)據(jù)slidingProgress回調(diào)至TargetListItem。
  3. 在TargetListItem中獲取回調(diào)的數(shù)據(jù)并刷新頁面。
// ProgressEditPanel.ets
@Component
export default struct ProgressEditPanel {
  @Link sliderMode: number;
  @Prop slidingProgress: number = 0;
  onCancel?: () = > void;
  onClickOK?: (progress: number) = > void;

  build() {
    Column() {
      Slider({...})
      Row() {
        CustomButton({
          buttonText: $r('app.string.cancel_button')
        })
          .onClick(() = > {
            if (this.onCancel !== undefined) {
              this.onCancel();
            }
          })
       CustomButton({
          buttonText: $r('app.string.cancel_button')
       })
          .onClick(() = > {
            if (this.onClickOK !== undefined) {
              this.onClickOK(this.slidingProgress);
            }
          })
      }
    }
  }
}

在DataModel.ets中,編寫updateProgress方法。該方法根據(jù)索引和進度值以及更新日期更新數(shù)據(jù)。

// DataModel.ets
updateProgress(index: number, updateValue: number, updateDate: string): boolean {
  if (!this.targetData[index]) {
    return false;
  }
  this.targetData[index].progressValue = updateValue;
  this.targetData[index].updateDate = updateDate;
  return true;
}

實現(xiàn)列表多選

列表進入編輯模式才可單選、多選。實現(xiàn)以下步驟完成列表多選功能:

  1. 維護一個boolean類型的數(shù)組selectArray,其長度始終與數(shù)據(jù)列表的長度相等,且初始值均為false。表示進入編輯狀態(tài)時列表均未選中。
  2. 定義一個boolean類型的值isEditMode,表示是否進入了編輯模式。
  3. TargetListItem選中狀態(tài)的初始化和點擊Checkbox改變TargetListItem的選中狀態(tài)。
// TargetList.ets
export default struct TargetList {
  ...
  @State isEditMode: boolean = false;
  @State selectArray: Array< boolean > = [];
  ...

  build() {
    Column() {
      ...
      if (this.isEditMode) {
        // 取消按鈕
        Text($r('app.string.cancel_button'))
          ...
          .onClick(() = > {
             this.selectAll = false;
             this.isEditMode = false;
             this.selectAllOrCancel(false);
          })
        ...
        // 全選按鈕
        Checkbox()
          ...
          .onClick(() = > {
            ...
            this.selectAllOrCancel(this.selectAll);
          })
      } else {
        // 編輯按鈕
        Text($r('app.string.edit_button'))
          ...
          .onClick(() = > {
            this.isEditMode = true;
            this.selectAllOrCancel(false);
          })
      }
      ...
    }
  }
}

點擊全選Checkbox,將selectArray數(shù)組的值全賦值true或false,重新渲染列表為全選或者取消全選狀態(tài)。

// TargetList.ets
selectAllOrCancel(selectStatus: boolean) {
  let newSelectArray: Array< boolean > = [];
  this.targetData.forEach(() = > {
    newSelectArray.push(selectStatus);
  });
  this.selectArray = newSelectArray;
}

在TargetListItem中,實現(xiàn)以下步驟改變ListItem的選中狀態(tài):

  1. 使用@Link定義selectArr數(shù)組接收TargetList傳入的selectArray。
  2. 在TargetListItem渲染時,使用this.selectArr[this.index]獲取初始選中狀態(tài)。
  3. 點擊Checkbox時,按照當(dāng)前ListItem的索引,將選中狀態(tài)保存至selectArr,重新渲染列表完成單選和多選功能。
// TargetListItem.ets
export default struct TargetListItem {

  ...
  @Link selectArr: Array< boolean >;
  public index: number = 0;
  
  build() {
    Stack({ alignContent: Alignment.Start }) {
      ...
      this.TargetItem()
      ...
      Checkbox()
        // 獲取初始選中狀態(tài)
        .select(this.selectArr[this.index])
        ...
        .onChange((isCheck: boolean) = > {
          // 改變被點擊項的選中狀態(tài)
          this.selectArr[this.index] = isCheck;
        })
      ...
    ...
    }
  }
}

實現(xiàn)刪除選中列表項

當(dāng)點擊“刪除”時,TargetList.ets的deleteSelected方法,實現(xiàn)以下步驟完成列表項刪除功能:

  1. 調(diào)用DataModel的deleteData方法刪除數(shù)據(jù)。
  2. 更新targetData的數(shù)據(jù)重新渲染列表。
  3. 修改overAllProgressChanged的值,通知主頁刷新整體進展詳情TargetInformation。
// TargetList.ets
deleteSelected() {
  DataModel.deleteData(this.selectArray);
  this.targetData = DataModel.getData();
  this.overAllProgressChanged = !this.overAllProgressChanged;
  this.isEditMode = false;
}

在DataModel.ets中,遍歷數(shù)據(jù)列表,刪除被選中的數(shù)據(jù)項。

// DataModel.ets
export class DataModel {
  ...
  deleteData(selectArr: Array< boolean >) {
    if (!selectArr) {
      Logger.error(TAG, 'Failed to delete data because selectArr is ' + selectArr);
    }
    let dataLen = this.targetData.length - CommonConstants.ONE_TASK;
    for (let i = dataLen; i >= 0; i--) {
      if (selectArr[i]) {
        this.targetData.splice(i, CommonConstants.ONE_TASK);
      }
    }
  }
  getData(): Array< TaskItemViewModel > {
    return this.targetData;
  }
  ...
}

審核編輯 黃宇

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

    關(guān)注

    1

    文章

    575

    瀏覽量

    17009
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2351

    瀏覽量

    42849
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3722

    瀏覽量

    16313
  • RK3568
    +關(guān)注

    關(guān)注

    4

    文章

    514

    瀏覽量

    5048
收藏 人收藏

    評論

    相關(guān)推薦

    HarmonyOS】應(yīng)用開發(fā)10-HarmonyOS開發(fā)者平臺和工具發(fā)布 - HDC2020

    發(fā)表于 11-05 18:16

    【官方資料】HDC技術(shù)論壇PPT分享-HarmonyOS應(yīng)用開發(fā)專場

    HarmonyOS】應(yīng)用開發(fā)10-HarmonyOS開發(fā)者平臺和工具發(fā)布 - HDC2020https://bbs.elecfans.co
    發(fā)表于 11-05 18:29

    【原創(chuàng)】IPC DIY攝像頭上手1

    存儲器接口TF卡最大支持128GB(通用FAT32格式)WLAN協(xié)議支持 802.11 b/g/n[td][/td][td]三、開發(fā)資料HarmonyOS 開發(fā)者平臺有設(shè)備和應(yīng)用的快速
    發(fā)表于 01-10 10:13

    HDD | HarmonyOS開發(fā)者日 上海站

    -------------------------------------------------------------------------------------HarmonyOS開發(fā)者日是華為為HarmonyOS的廣大
    發(fā)表于 04-01 15:55

    HarmonyOS開發(fā)者

    HarmonyOS開發(fā)者,HarmonyOS設(shè)備開發(fā)學(xué)習(xí)路線HarmonyOS 2.0如約而至,內(nèi)存在128KB~128MB的終端設(shè)備廠商有
    發(fā)表于 07-22 09:53

    絕對干貨!HarmonyOS開發(fā)者日資料全公開,鴻蒙開發(fā)者都在看

    731HarmonyOS開發(fā)者日大會PPT資料全在這了,想要了解的小伙伴可以自行下載啦~下載資料的小伙伴還可以在評論區(qū)回復(fù)領(lǐng)取5個積分哦1、HarmonyOS 職業(yè)認證解讀:該主題是開發(fā)者
    發(fā)表于 08-04 14:36

    請問海外開發(fā)者如何開發(fā)HarmonyOS應(yīng)用?

    海外開發(fā)者如何開發(fā)HarmonyOS應(yīng)用?
    發(fā)表于 06-02 15:50

    喜報|HarmonyOS開發(fā)者社區(qū)連獲業(yè)內(nèi)獎項,持續(xù)深耕開發(fā)者生態(tài)

    臨近年末,各大平臺陸續(xù)揭曉年度榜單,表彰了具備強大影響力與做出突出貢獻的優(yōu)秀項目與團隊,而HarmonyOS開發(fā)者社區(qū)作為技術(shù)分享,學(xué)習(xí)和展示的平臺,輸出高質(zhì)量技術(shù)文章百余篇,連續(xù)獲得
    發(fā)表于 01-19 14:32

    華為開發(fā)者HarmonyOS零基礎(chǔ)入門:四步實現(xiàn)HarmonyOS應(yīng)用

    華為開發(fā)者HarmonyOS零基礎(chǔ)入門:四步實現(xiàn)HarmonyOS應(yīng)用,可以自定義主鍵實際應(yīng)用在開發(fā)者界面。
    的頭像 發(fā)表于 10-23 10:05 ?1948次閱讀
    華為<b class='flag-5'>開發(fā)者</b><b class='flag-5'>HarmonyOS</b>零基礎(chǔ)入門:四步實現(xiàn)<b class='flag-5'>HarmonyOS</b>應(yīng)用

    華為開發(fā)者大會2021 HarmonyOS 3開發(fā)者預(yù)覽版

    華為開發(fā)者大會2021上,隨著全新的 HarmonyOS 3 開發(fā)者預(yù)覽版發(fā)布,HarmonyOS 應(yīng)用與服務(wù)開發(fā)工具套件全家桶也全面升級,
    的頭像 發(fā)表于 10-23 11:20 ?1358次閱讀
    華為<b class='flag-5'>開發(fā)者</b>大會2021 <b class='flag-5'>HarmonyOS</b> 3<b class='flag-5'>開發(fā)者</b>預(yù)覽版

    華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-10分鐘成為HarmonyOS開發(fā)者

    2021華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-10分鐘成為HarmonyOS開發(fā)者
    的頭像 發(fā)表于 10-24 11:03 ?1933次閱讀
    華為<b class='flag-5'>開發(fā)者</b>分論壇<b class='flag-5'>HarmonyOS</b>學(xué)生公開課-10分鐘成為<b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)者</b>

    華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-如何學(xué)習(xí)HarmonyOS應(yīng)用開發(fā)?

    2021華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-如何學(xué)習(xí)HarmonyOS應(yīng)用開發(fā)?
    的頭像 發(fā)表于 10-24 11:09 ?2138次閱讀
    華為<b class='flag-5'>開發(fā)者</b>分論壇<b class='flag-5'>HarmonyOS</b>學(xué)生公開課-如何學(xué)習(xí)<b class='flag-5'>HarmonyOS</b>應(yīng)用<b class='flag-5'>開發(fā)</b>?

    2021華為開發(fā)者大會HarmonyOS學(xué)生公開課上教你10分鐘成為HarmonyOS開發(fā)者

    2021華為開發(fā)者大會HarmonyOS學(xué)生公開課上教你10分鐘成為HarmonyOS開發(fā)者 學(xué)習(xí)HarmonyOS應(yīng)用
    的頭像 發(fā)表于 10-24 11:03 ?2136次閱讀
    2021華為<b class='flag-5'>開發(fā)者</b>大會<b class='flag-5'>HarmonyOS</b>學(xué)生公開課上教你10分鐘成為<b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)者</b>

    華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-開發(fā)者成長圖譜

    2021華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-開發(fā)者成長圖譜
    的頭像 發(fā)表于 10-24 11:25 ?1975次閱讀
    華為<b class='flag-5'>開發(fā)者</b>分論壇<b class='flag-5'>HarmonyOS</b>學(xué)生公開課-<b class='flag-5'>開發(fā)者</b>成長圖譜

    面向HarmonyOS開發(fā)者HarmonyOS 3.0 Beta介紹

    2021年10月,我們面向開發(fā)者發(fā)布了HarmonyOS 3.0 Developer Preview版,但開發(fā)的腳步永不停歇,現(xiàn)在我們又更新了API版本,配套發(fā)布了HarmonyOS
    的頭像 發(fā)表于 07-06 20:34 ?3308次閱讀