在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

HarmonyOS開發實例:【手機備忘錄】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-18 21:40 ? 次閱讀

介紹

本篇Codelab基于用戶首選項,實現了備忘錄新增、更新、刪除以及查找等功能。效果如圖所示:

相關概念

  • [用戶首選項]:提供Key-Value鍵值型的數據處理能力,應用持久化輕量級數據,并對其修改和查詢。
  • [Navigator]:路由容器組件,支持路由跳轉以及子組件嵌入。

環境搭建

軟件要求

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

硬件要求

  • 開發板類型:[潤和RK3568開發板]。
  • OpenHarmony系統:3.2 Release。

環境搭建

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

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

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

代碼結構解讀

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

├──entry/src/main/ets           // 代碼區
│  ├──common
│  │  ├──constants
│  │  │  ├──CommonConstants.ets // 常量類 
│  │  │  └──StyleConstants.ets  // 樣式常量類 
│  │  └──utils
│  │     ├──Format.ets          // 日期格式化函數
│  │     └──Logger.ets          // 日志打印類
│  ├──entryability
│  │  └──EntryAbility.ts        // 程序入口類
│  ├──model
│  │  └──NotesDataModel.ets     // 備忘錄方法類
│  ├──pages
│  │  ├──NoteHomePage.ets       // 備忘錄主頁面(列表頁)
│  │  └──NotesDetail.ets        // 備忘錄詳情頁	
│  ├──view
│  │  ├──BottomBar.ets          // 備忘錄編輯頁底部欄
│  │  ├──ConfirmDialog.ets      // 自定義彈窗
│  │  └──MemoItem.ets           // 自定義備忘錄列表組件
│  └──viewmodel
│     └──NotesInfoViewModel.ets // 備忘錄默認數據實體	
└──entry/src/main/resources     // 資源文件目錄

備忘錄初始化

在這個章節中,需要實現備忘錄數據的初始化,并且通過List組件將其渲染出來。效果如圖所示:

在saveDefaultData方法中先通過getPreferences方法獲取preferences實例,然后調用has方法查找數據庫中是否存在“noteIdArr”這個key值,如果不存在調用實例的put方法將noteIdArr以及備忘錄數據寫入,最后通過flush方法進行數據持久化。

// NotesDataModel.ets
import dataStorage from '@ohos.data.preferences';
...
class NotesDataModel {
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

  /**
   * 寫入備忘錄數據.
   */
  async saveDefaultData() {
    try {
      let preferences = await dataStorage.getPreferences(this.context, CommonConstants.PREFERENCE_INSTANCE_NAME);
      let isExist = await preferences.has(CommonConstants.PREFERENCE_NOTE_KEY);
      if (!isExist) {
        preferences.put(CommonConstants.PREFERENCE_NOTE_KEY, JSON.stringify(noteIdArray));
        preferences.flush();
        notesItemArr.forEach((item: NotesInfoBean) = > {
          let notes: NotesInfoBean = item;
          let res = preferences.put(item.noteId, JSON.stringify(notes));
          preferences.flush();
          res.then(() = > {
            Logger.info('Put the value successfully.' + item.noteId);
          }).catch((err: Error) = > {
            Logger.error(`Put the value failed with err: ${err}`);
          })
        })
      }
    } catch (err) {
      Logger.error(`Failed to get preferences. Error = ${err}`);
    }
  }

  /**
   * 基于筆記類型獲取對應備忘錄數據.
   *
   * @param flag the folder type.
   * @param allNotes all of notes.
   * @returns subNotes.
   */
  getSelectNotes(flag: FolderType, allNotes: Array< NotesInfoBean >): Array< NotesInfoBean > {
    return allNotes.filter((item: NotesInfoBean) = > item.folder === flag);
  }
}

在NoteHomePage.ets文件中調用saveDefaultData函數先將本地數據寫入數據庫,再調用實例的get方法進行查詢操作。

// NoteHomePage.ets
import dataStorage from '@ohos.data.preferences';
...
@Entry
@Component
struct NoteHomePage {
  @State folderType: Resource = $r('app.string.notes_all');
  @State allNotes: Array< NotesInfoBean > = [];
  @State selectNotes: Array< NotesInfoBean > = this.allNotes.sort();
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  ...
  build() {
    Column() {
      ...
      List({ space: StyleConstants.MEMO_LIST_SPACE }) {
        ForEach(this.selectNotes, (item: NotesInfoBean) = > {
          ListItem() {
            MemoItem({ noteItem: item })
          }
        }, (item: NotesInfoBean) = > JSON.stringify(item))
      }
      .margin({ top: $r('app.float.list_container_margin') })
      .height(StyleConstants.NOTE_CONTENT_HEIGHT)
      .width(StyleConstants.FULL_WIDTH)
    }
    .backgroundColor($r('app.color.page_background'))
    .height(StyleConstants.FULL_HEIGHT)
  }

  onPageShow() {
    this.getAllNotes();
  }

  async getAllNotes() {
    await NotesDataModel.saveDefaultData();
    try {
      let preferences = await dataStorage.getPreferences(this.context, CommonConstants.PREFERENCE_INSTANCE_NAME);
      let noteIds = await preferences.get(CommonConstants.PREFERENCE_NOTE_KEY, '');
      while (this.allNotes.length >= 1) {
        this.allNotes.pop();
      }
      JSON.parse(noteIds.toString()).forEach(async (item: NotesInfoBean) = > {
        let note = await preferences.get(item.noteId, '');
        this.allNotes.push(JSON.parse(note.toString()));
      })
    } catch (err) {
      Logger.error('Get the value of noteIdArr failed with err:', err);
    }
  }
}

新增備忘錄

此章節介紹新增備忘錄功能,點擊列表頁右上角加號進入編輯頁,支持輸入標題、備忘錄內容以及添加圖片。效果如圖所示:

首先在列表頁NoteHomePage.ets中添加跳轉邏輯,設置路由參數params,其中operationType字段代表此次操作是新增還是修改。

// NoteHomePage.ets
Navigator({ target: 'pages/NotesDetail', type: NavigationType.Replace }) {
  Row() {
    Image($rawfile('ic_title_add.svg'))
      ...
  }
  .margin({ right: $r('app.float.note_add_margin') })
}
.params({
  notesInfo: {
    'noteId': new Date().getTime().toString(),
    'title': '',
    'folder': FolderType.Personal,
    'content': '',
    'imageArr': [],
    'time': new Date().toTimeString().split(' ')[0],
    'isFavorite': false
  },
  operationType: CommonConstants.ADD_NOTE
})

進入編輯頁NotesDetail.ets后可以輸入標題、內容以及選擇對應的筆記類型等,確認保存后備忘錄數據實時更新。

// NotesDetail.ets
build() {
  ...
  TextInput({
    text: this.notesInfo.title != '' ? this.notesInfo.title : '',
    placeholder: this.notesInfo.title != '' ? '' : $r('app.string.note_title_placeholder')
  })
    ...
    .onChange((value: string) = > {
      if (value !== this.notesInfo.title) {
        this.notesInfo.title = value;
        this.isDataChanged = true;
      }
    })
  ...
  TextArea({
    text: this.notesInfo.content !== '' ? this.notesInfo.content : '',
    placeholder: this.notesInfo.content !== '' ? '' : $r('app.string.note_content_placeholder')
  })
    .onChange((value: string) = > {
      if (value !== this.notesInfo.content) {
        this.notesInfo.content = value;
        this.isDataChanged = true;
      }
    })
  ...
}

onBackPress() {
  if (this.isDataChanged || this.notesFolder !== this.notesInfo.folder || this.isCollectChange) {
    this.saveDialogController.open();
  } else {
    router.replaceUrl({
      url: 'pages/NoteHomePage'
    });
  }
  return true;
}

// ConfirmDialog.ets
if (this.type === CommonConstants.SAVE_DIALOG) {
  this.confirm = async () = > {
    let preferences = await dataStorage.getPreferences(this.context, CommonConstants.PREFERENCE_INSTANCE_NAME);
    // 保存備忘錄數據實時更新
    if (this.operationType === CommonConstants.ADD_NOTE) {
      this.noteIdArray.push(new NoteIdBean(this.notesInfo.noteId));
      preferences.put(CommonConstants.PREFERENCE_NOTE_KEY, JSON.stringify(this.noteIdArray));
      preferences.flush();
    }
    let newNotes = this.notesInfo;
    await preferences.put(this.notesInfo.noteId, JSON.stringify(newNotes));
    await preferences.flush();
    router.replaceUrl({
      url: 'pages/NoteHomePage'
    });
  }
}

更新備忘錄

此章節介紹更新數據庫操作,與新增備忘錄邏輯類似。效果如圖所示:

首先在NotesDetail.ets中設置isDataChange和isCollectChange屬性,來表示對應noteId的備忘錄數據是否已更改。如果isDataChange或者isCollectChange為true表示已更改,在返回列表頁時會拉起確認彈窗,確認保存后執行put方法去更改備忘錄數據。

// NotesDetail.ets
build() {
  Column() {
    ...
    Stack({ alignContent: Alignment.Bottom }) {
      Scroll(this.scroller) {
        Column() {
          TextInput({
            text: this.notesInfo.title != '' ? this.notesInfo.title : '',
            placeholder: this.notesInfo.title != '' ? '' : $r('app.string.note_title_placeholder')
          })
            ...
            .onChange((value: string) = > {
              if (value !== this.notesInfo.title) {
                this.notesInfo.title = value;
                this.isDataChanged = true;
              }
            })
          ...
          TextArea({
            text: this.notesInfo.content !== '' ? this.notesInfo.content : '',
            placeholder: this.notesInfo.content !== '' ? '' : $r('app.string.note_content_placeholder')
          })
            .onChange((value: string) = > {
              if (value !== this.notesInfo.content) {
                this.notesInfo.content = value;
                this.isDataChanged = true;
              }
            })
          ...
        }
      }
      ...
      BottomBar({
        imageArr: $imageArr,
        notesInfo: $notesInfo,
        operationType: $operationType,
        noteIdArray: $noteIdArray,
        isDataChanged: $isDataChanged
      })
    }
    ...
  }
  .height(StyleConstants.FULL_HEIGHT)
  .backgroundColor($r('app.color.white_color'))
}
...
onBackPress() {
  if (this.isDataChanged || this.notesFolder !== this.notesInfo.folder || this.isCollectChange) {
    this.saveDialogController.open();
  } else {
    router.replaceUrl({
      url: 'pages/NoteHomePage'
    });
  }
  return true;
}

// BottomBar.ets
// 點擊收藏
this.clickCollect = () = > {
  this.notesInfo.isFavorite = !this.notesInfo.isFavorite;
  this.isFavorite = !this.isFavorite;
  this.collectImgSrc = this.notesInfo.isFavorite ?
    'ic_bottom_star_selected.svg' : 'ic_bottom_star_normal.svg';
}
...
// 點擊插入圖片
this.clickAddPicture = () = > {
  this.imageSrc = this.chooseImage();
  if (this.imageSrc === '') {
    prompt.showToast({
      message: 'Not anymore pictures'
    });
  } else {
    this.imageArr = this.notesInfo.imageArr;
    this.imageArr.push(this.imageSrc);
    this.isDataChanged = true;
  }
}

// ConfirmDialog.ets
if (this.type === CommonConstants.SAVE_DIALOG) {
  this.confirm = async () = > {
    let preferences = await dataStorage.getPreferences(this.context, CommonConstants.PREFERENCE_INSTANCE_NAME);
    if (this.operationType === CommonConstants.ADD_NOTE) {
      this.noteIdArray.push(new NoteIdBean(this.notesInfo.noteId));
      preferences.put(CommonConstants.PREFERENCE_NOTE_KEY, JSON.stringify(this.noteIdArray));
      preferences.flush();
    }
    // 保存備忘錄數據實時更新
    let newNotes = this.notesInfo;
    await preferences.put(this.notesInfo.noteId, JSON.stringify(newNotes));
    await preferences.flush();
    router.replaceUrl({
      url: 'pages/NoteHomePage'
    });
  }
}

刪除備忘錄

上述章節介紹了數據庫的新增與更新,此章節來介紹刪除操作。效果如圖所示:

在BottomBar.ets中點擊刪除按鈕,彈出自定義彈窗選擇“是否刪除”。在ConfirmDialog.ets中添加刪除邏輯,刪除操作會調用preferences實例的delete方法,將對應noteId的備忘錄數據從數據庫中刪除,最后執行實例的flush方法實現持久化。

// BottomBar.ets
export default struct BottomBar {
  ...
  deleteDialogController: CustomDialogController = new CustomDialogController({
    builder: ConfirmDialog({
      notesInfo: $notesInfo,
      operationType: $operationType,
      noteIdArray: $noteIdArray,
      type: CommonConstants.DELETE_DIALOG
    }),
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: $r('app.float.dialog_offset_x'), dy: $r('app.float.dialog_margin_bottom') }
  });
  ...
  build() {
    ...
    Column() {
      Image($r('app.media.ic_bottom_delete'))
        .width($r('app.float.ic_bottom_picture_size'))
        .aspectRatio(1)
      Text($r('app.string.delete_note'))
        .fontSize($r('app.float.font_size_smallest'))
        .margin({ top: $r('app.float.bottom_txt_margin') })
    }
    .onClick(() = > {
      this.clickDelete = () = > {
        if (this.operationType === CommonConstants.MODIFY_NOTE) {
          this.deleteDialogController.open();
        } else {
          prompt.showToast({
            message: 'The addition operation cannot be deleted'
          });
        }
      }
      this.clickDelete();
    })
    ...
  }
  ...
}

// ConfirmDialog.ets
if (this.type === CommonConstants.SAVE_DIALOG) {
  ...
} else {
  // 刪除備忘錄數據
  this.confirm = async () = > {
    let preferences = await dataStorage.getPreferences(this.context, CommonConstants.PREFERENCE_INSTANCE_NAME);
    await preferences.delete(this.notesInfo.noteId);
    await preferences.flush();
    router.replaceUrl({
      url: 'pages/NoteHomePage'
    });
  }
}
this.confirm();
})

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 鴻蒙
    +關注

    關注

    57

    文章

    2395

    瀏覽量

    43091
  • HarmonyOS
    +關注

    關注

    79

    文章

    1983

    瀏覽量

    30630
  • OpenHarmony
    +關注

    關注

    25

    文章

    3753

    瀏覽量

    16661
收藏 人收藏

    評論

    相關推薦

    PostgreSQL操作備忘錄

    PostgreSQL 操作備忘錄
    發表于 05-23 08:48

    UDS診斷命令備忘錄

    UDS實踐性強,邏輯復雜,很多服務非要體驗過一次才能理解,導致包括我在內的初學者感覺晦澀難懂,不明覺厲,因此將自己的理解寫下來、整理下來,與君共勉。零、UDS診斷命令備忘錄一、簡介UDS
    發表于 08-26 16:09

    怎樣去搭建一種基于XR806的開源桌面備忘錄

    本人計劃懟一個開源桌面備忘錄/天氣預報/相冊的項目基于XR806,同時學習鴻蒙操作系統獲得暈哥贈送的開發板和芯片,目前處于環境搭建階段看起來這個芯片玩的人比較少,目前遇到了問題,不知道如何解決,希望
    發表于 12-28 06:52

    全球半導體聯盟與中國半導體行業簽署合作備忘錄

    全球半導體聯盟與中國半導體行業簽署合作備忘錄 全球半導體聯盟(GSA)與中國半導體行業協會(CSIA)在蘇州聯合申明簽署合作備忘錄。此次合作將為促
    發表于 09-24 08:17 ?716次閱讀

    戴姆勒與百度簽署諒解備忘錄

    7月25日,奔馳母公司戴姆勒與百度簽署諒解備忘錄,深化雙方在自動駕駛和車聯網等領域的戰略合作。
    的頭像 發表于 07-28 09:53 ?2767次閱讀

    怎樣將蘋果備忘錄筆記Notes“安裝”到Win10上

    用iPhone、iPad的朋友一直有這樣一個困惑,在手機平板上記錄的蘋果Notes備忘錄筆記,要怎么在電腦上查看?
    的頭像 發表于 03-31 16:22 ?6874次閱讀

    Vedanta與30家日本公司簽署諒解備忘錄

    印度Vedanta Group已與30家日本公司簽署諒解備忘錄,以開發印度半導體和玻璃顯示器制造生態系統。上周在日本東京舉行的2022年Vedanta-Avanstrate商業合作伙伴峰會上簽署了這些備忘錄,來自100多家全球公
    的頭像 發表于 12-15 09:12 ?1009次閱讀

    設計模式:備忘錄設計模式

    備忘錄設計模式(Memento Design Pattern)是一種行為型設計模式,它的主要目的是在不破壞對象封裝性的前提下,捕捉和保存一個對象的內部狀態
    的頭像 發表于 06-06 11:19 ?842次閱讀

    設計模式行為型:備忘錄模式

    備忘錄模式(Memento Pattern)保存一個對象的某個狀態,以便在適當的時候恢復對象。備忘錄模式屬于行為型模式。
    的頭像 發表于 06-07 11:16 ?901次閱讀
    設計模式行為型:<b class='flag-5'>備忘錄</b>模式

    新思科技同越南政府簽署諒解備忘錄

    在越南總理范明政訪美期間,新思科技與越南國家創新中心(nic)簽署了關于培養越南集成電路設計人才的諒解備忘錄,支持nic成立芯片設計孵化中心。另外,新思科技與越南信息通訊部下屬的信息通信技術產業公司簽訂了支援越南半導體產業發展的諒解備忘錄
    的頭像 發表于 09-20 10:56 ?1604次閱讀

    實踐GoF的23種設計模式:備忘錄模式

    相對于代理模式、工廠模式等設計模式,備忘錄模式(Memento)在我們日常開發中出鏡率并不高,除了應用場景的限制之外,另一個原因,可能是備忘錄模式
    的頭像 發表于 11-25 09:05 ?604次閱讀
    實踐GoF的23種設計模式:<b class='flag-5'>備忘錄</b>模式

    江汽與華為簽訂合作備忘錄 發力鴻蒙

    江汽與華為簽訂合作備忘錄進一步深化雙方合作;共同發力鴻蒙,江汽與華為將以OpenHarmony為底座的HarmonyOS啟動鴻蒙原生應用開發;為用戶提供更智能的體驗。
    的頭像 發表于 03-27 16:00 ?1004次閱讀

    蘋果iOS 18將支持語音備忘錄及數學符號顯示

    首先是語音備忘錄功能。據悉,蘋果有意在iOS 18系統中加入此項功能,使iPhone用戶能夠便捷地錄制音頻文件,并將其直接嵌入至備忘錄之中。
    的頭像 發表于 04-18 11:14 ?611次閱讀

    英飛凌與韓國造船海洋簽署合作備忘錄

    近日,全球功率半導體巨頭英飛凌科技與韓國造船海洋(HD KSOE)共同簽署了一份諒解備忘錄(MoU)。此次合作旨在推動低碳節能,通過功率半導體技術聯合開發新型船用發動機和推動船舶機械電氣化。
    的頭像 發表于 05-07 15:15 ?560次閱讀

    黑芝麻智能與Dirac簽署合作備忘錄

    1月21日,黑芝麻智能與Dirac簽署合作備忘錄,雙方將基于黑芝麻智能武當C1200家族芯片共同探索汽車高品質音頻體驗的創新。
    的頭像 發表于 01-21 10:48 ?148次閱讀
    主站蜘蛛池模板: 亚洲综合在线最大成人 | 黄色大片三级 | 亚洲综合日韩欧美一区二区三 | 午夜宅男在线 | 日本一区高清视频 | 亚洲91在线视频 | 91大神大战丝袜美女在线观看 | 婷婷影院在线综合免费视频 | 性试验k8经典 | 欧美三级免费网站 | 成人男女啪啪免费观看网站 | 亚洲伊人成综合成人网 | 福利片欧美 | 亚洲va老文色欧美黄大片人人 | 国内一国产农村妇女一级毛片 | 免费人成年激情视频在线观看 | 欧美日韩一区二区三区视频 | 久久精品波多野结衣 | 国产高清一区二区三区四区 | 四虎影视色费永久在线观看 | 色多多在线看 | 欧美视频小说 | 亚洲射图 | 美女黄频 | 天堂资源最新版在线官网 | 欧美一区二区在线观看视频 | 在线天堂bt种子 | 午夜精 | 国产三级在线观看 | 欧美色综合久久 | 久久国产视频一区 | 成人黄色在线 | 一级网站片 | 日韩成人黄色 | 在线免费看黄 | 在线观看一级毛片 | 亚洲综合色吧 | 四虎网站最新网址 | 亚洲国产精品综合久久2007 | 在线观看日本免费视频大片一区 | 国产毛片精品 |