動態

詳情 返回 返回

【推薦+1】HarmonyOS官方模板優秀案例 (第4期:餐飲行業 · 美食菜譜) - 動態 詳情

💡 鴻蒙生態為開發者提供海量的HarmonyOS模板/組件,助力開發效率原地起飛 💡

★ 一鍵直達生態市場組件&模板市場 , 快速應用DevEco Studio插件市場集成組件&模板 ★

好用的菜譜APP能夠幫助飲食管理事半功倍!

小編本期為大家介紹餐飲行業案例

👉 覆蓋20+行業,本帖以彙總形式持續更新中,點擊收藏!一鍵三連!常看常新!

【第4期】餐飲行業 · 美食菜譜

一、概述

1. 行業洞察

1)行業痛點:

  • 傳統餐飲私域流量缺失,依賴第三方平台導流,佣金成本高且較難沉澱用户。
  • 網絡菜譜步驟描述模糊,用料配比不精確,成功率低。
  • 個性化不足:缺乏根據用户口味偏好、飲食限制(素食/低糖/無麩質)的智能推薦。
  • 購物不便:菜譜食材無法一鍵購買,特殊調料難以配齊。
  • 數據價值未挖掘:用户烹飪行為數據未形成精準畫像。
  • 互動體驗差:用户作品分享渠道單一,缺乏專業廚師點評指導。

2)行業常用三方SDK

分類

三方庫名稱

功能

支持情況

SDK鏈接

媒體

阿里雲視頻播放器SDK

音視頻

已支持

支付寶SDK

微信支付SDK

銀聯SDK

騰訊QQ SDK

新浪微博SDK

極光PUSH SDK

友盟移動統計SDK

騰訊微信SDK

高德地圖SDK

個推

Bugly

ShareSDK

聽雲SDK

登錄認證

中國移動一鍵登錄SDK/易盾一鍵登錄SDK/創藍閃驗/極光安全認證/阿里雲號碼認證SDK/中國電信一鍵登錄SDK

登錄

已支持

分享

友盟/ShareSDK/微信分享/QQ分享/新浪微博SDK/MobTech ShareSDK

統計/推送/分享

已支持

支付

支付寶支付/微信支付/銀聯支付

支付

已支持

數據分析

友盟移動統計SD/神策數據SDK

數據收集、處理、分析、運用

已支持

性能監控

騰訊Bugly SDK/聽雲SDK/嶽鷹全景監控SDK

異常上報和運營統計

已支持

地圖

高德地圖SDK

地圖

已支持

推送

個推/華為推送/極光PUSH/阿里推送SDK

消息推送

已支持

媒體

阿里雲視頻播放器SDK

音視頻

已支持

説明:“以上三方庫及鏈接僅為示例,三方庫由三方開發者獨立提供,以其官方內容為準”

2. 案例概覽(下載模板)

基於以上行業分析,本期將介紹鴻蒙生態市場餐飲行業模板——美食菜譜應用模板,為行業提供常用功能的開發案例,涵蓋分類搜索、作品分享、菜譜用料、熱量計算、飲食計劃等多個實用功能。

  • Stage開發模型 + 聲明式UI開發範式。
  • 分層架構設計 + 組件化拆分,支持開發者在開發時既可以選擇完整使用模板,也可以根據需求單獨選用其中的業務組件。
  • 集成華為賬號、支付等服務,只需做少量配置和定製即可快速實現華為賬號的登錄、菜譜上傳等功能。

本模板主要頁面及核心功能如下所示:

二、應用架構設計

1. 分層模塊化設計

  • 產品定製層:專注於滿足不同設備或使用場景的個性化需求,作為應用的入口,是用户直接互動的界面。
    • 本實踐暫時只支持直板機,為單HAP包形式,包含路由根節點、底部導航欄等。
  • 基礎特性層:用於存放相對獨立的功能UI和業務邏輯實現。
    • 本實踐的基礎特性層將應用底部導航欄的每個選項拆分成一個獨立的業務功能模塊,包含首頁、分類、熱量計算和我的。
    • 每個功能模塊都具備高內聚、低耦合、可定製的特點,支持產品的靈活部署。
  • 公共能力層:存放公共能力,包括公共UI組件、數據管理、外部交互和工具庫等共享功能。
    • 本實踐的公共能力層分為公共基礎能力和可分可合組件,均打包為HAR包被上層業務組件引用。
    • 公共基礎能力包含日誌、文件處理等工具類,公共類型定義,網絡庫,以及彈窗、加載等公共組件。
    • 可分可合組件將包含行業特點、可完全自閉環的能力抽出獨立的組件模塊,支持開發者在開發中單獨集成使用,詳見業務組件設計章節。

http://image.huawei.com/tiny-lts/v1/images/hi3ms/edf690f19332784457ac85f9514db6d1_1226x503.png

2. 業務組件設計

為支持開發者單獨獲取特定場景的頁面和功能,例如開發者已搭建了一個自己的美食菜譜元服務工程,只想單獨取用本模板中的菜籃子或熱量計算功能,本模板將功能完全自閉環的部分能力抽離出獨立的行業組件模塊,不依賴公共基礎能力包,開發者可以單獨集成,開箱即用,降低使用難度。

http://image.huawei.com/tiny-lts/v1/images/hi3ms/0b4b99b97dd7af53b8f480b111944486_1160x399.png

三、行業場景技術方案

1. 賬號管理

1)場景説明

支持華為賬號一鍵登錄及其他方式(賬號密碼登錄、微信登錄)。

用户登錄後展示暱稱和頭像,點擊用户信息欄可進入用户主頁,查看並編輯個人信息。

2)技術方案

  • 華為賬號一鍵登錄
    • 通過Account Kit實現華為賬號一鍵登錄,並獲取用户手機號,關聯應用已有用户。
  • 微信登錄
    • 根據鴻蒙接入指南接入微信SDK,可通過跳轉微信並獲取微信用户授權進行登錄。
  • 頭像修改
    • 通過Scenario Fusion Kit提供的選擇頭像Button快速拉起頭像選擇頁面,供用户完成華為賬號頭像或其他頭像的選擇與展示。

3)代碼參考

  • 部分核心代碼參見個人信息實現章節。

2. 分類搜索

1)場景説明

  • 支持按菜譜分類展示和搜索菜譜,點擊菜譜可以查看菜譜詳細信息。

2)技術方案

使用List和Grid組件實現分類列表的展示、連續滾動以及搜索結果展示。

3)代碼參考

  • 部分核心代碼參見分類搜索實現章節。

3. 飲食計劃

1)場景説明

支持制定飲食計劃的食材,也可以自定義食材並填寫熱量。

2)技術方案

  • 列表展示
  • 使用List和ListItemGroup實現列表的連續滾動,並快速滾動到指定分類。
  • 自定義添加食物
  • 使用bindSheet方法對當前頁面綁定半模態彈框,實現自定義食物的添加。

4. 熱量計算

1)場景説明

支持查看當日飲食熱量攝入情況,或者查看一週熱量攝入統計。

2)技術方案

  • 使用Progress繪製環形數據統計,使用LinearGradient實現環形顏色的漸變效果。
  • 使用三方庫@ohos/mpchart繪製柱狀圖,展示一週熱量攝入信息。

3)代碼參考

  • 部分核心代碼參見熱量計算實現章節。

四、模板代碼

1. 工程結構(下載模板)

詳細代碼結構如下所示:

Recipes
  ├─commons/commonlib/src/main
  │  ├─ets
  │  │  ├─components
  │  │  │      BaseHeader.ets                 // 一級頁面標題組件
  │  │  │      BuildTitleBar.ets              // 二級頁面標題組件
  │  │  │      HeaderMenuBuilder.ets          // 標題菜單內容組件
  │  │  │      MenuItemBuilder.ets            // 下拉菜單選項
  │  │  ├─constants
  │  │  │      CommonContants.ets             // 公共常量
  │  │  │      CommonEnums.ets                // 公共枚舉值
  │  │  ├─types
  │  │  │      Types.ets                      // 公共抽象類
  │  │  └─utils
  │  │         AccountUtil.ets                // 賬號工具類
  │  │         DialogUtil.ets                 // 彈窗工具類
  │  │         FormatUtil.ets                 // 格式化工具類
  │  │         Logger.ets                     // 日誌工具類
  │  │         PermissionUtil.ets             // 權限獲取工具類
  │  │         PreferenceUtil.ets             // 數據持久化工具類
  │  │         RouterModule.ets               // 路由工具類
  │  │         WindowUtil.ets                 // 窗口管理工具類
  │  └─resources
  ├─commons/network/src/main
  │  ├─ets
  │  │  ├─apis
  │  │  │      APIList.ets                    // 網絡請求API
  │  │  │      HttpRequest.ets                // 網絡請求
  │  │  ├─mocks
  │  │  │  └─MockData
  │  │  │         Calories.ets                // 熱量mock數據
  │  │  │         Mine.ets                    // 我的mock數據
  │  │  │         Notice.ets                  // 通知mock數據
  │  │  │         RecipeList.ets              // 菜譜mock數據
  │  │  │      AxiosMock.ets                  // mock請求
  │  │  │      RequestMock.ets                // mock API
  │  │  └─types
  │  │         Calories.ets                   // 熱量抽象類
  │  │         Member.ets                     // 會員抽象類
  │  │         Notice.ets                     // 通知抽象類
  │  │         Recipe.ets                     // 菜譜抽象類
  │  └─resources
  │─components/aggregated_ads/src/main   
  │  ├─ets
  │  │  ├─common
  │  │  │      Constant.ets                   // 常量類
  │  │  ├─components
  │  │  │      AdServicePage.ets              // 廣告服務組件
  │  │  │      HwAdService.ets                // 華為廣告
  │  │  ├─util
  │  │  │      UIUtil.ets                     // UI工具類
  │  │  └─viewmodel
  │  │         AggreagetedAdVM.ets            // 廣告頁面數據模型
  │  └─resources
  │─components/aggregated_login/src/main   
  │  ├─ets
  │  │  ├─common
  │  │  │      Constant.ets                   // 常量類
  │  │  │      Logger.ets                     // 日誌類
  │  │  ├─components
  │  │  │      AgreementDialog.ets            // 協議彈窗組件
  │  │  │      LoginService.ets               // 登錄組件
  │  │  ├─model
  │  │  │      Index.ets                      // 數據類型
  │  │  │      WXApiWrap.ets                  // 微信登錄數據類型
  │  │  └─viewmodel
  │  │         AggregatedLoginVM.ets          // 登錄組件數據模型
  │  └─resources
  │─components/aggregated_payment/src/main   
  │  ├─ets
  │  │  ├─common
  │  │  │      Constant.ets                   // 常量類
  │  │  ├─components
  │  │  │      AggregatedPaymentPicker.ets    // 支付組件
  │  │  ├─model
  │  │  │      Index.ets                      // 數據類型
  │  │  │      WXApiWrap.ets                  // 微信支付數據類型
  │  │  └─viewmodel
  │  │         AggregatedPaymentVM.ets        // 支付組件數據模型
  │  └─resources
  │─components/base_ui/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      BaseTabs.ets                   // Tabs組件
  │  │  └──types
  │  │         Index.ets                      // 數據類型
  │  └─resources
  │─components/calorie_calculation/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      BarChart.ets                   // 協議彈窗組件
  │  │  │      CalorieCalculation.ets         // 熱量計算組件
  │  │  │      CaloriesSummary.ets            // 熱量彙總組件
  │  │  │      FoodDiary.ets                  // 飲食計劃組件
  │  │  ├─types
  │  │  │      Index.ets                      // 數據類型
  │  │  └─viewModels
  │  │         CaloriesSummaryVM.ets          // 熱量計算數據模型
  │  └─resources
  │─components/featured_recipes/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      FeaturedRecipes.ets            // 菜譜瀑布流組件
  │  │  │      RecommendedCard.ets            // 菜譜卡片
  │  │  │─types
  │  │  │      Index.ets                      // 數據類型
  │  │  └─utils
  │  │         LazyDataSource.ets             // 懶加載對象
  │  │         Logger.ets                     // 日誌工具
  │  │         ObservedArray.ets              // 數組監聽工具
  │  └─resources
  │─components/home_search/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      HomeSearch.ets                 // 搜索組件
  │  │  │      SearchKeys.ets                 // 熱搜詞組件
  │  │  │      SearchResult.ets               // 搜索結果組件
  │  │  └─types
  │  │         Index.ets                      // 數據類型
  │  └─resources
  │─components/link_category/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      LinkCategory.ets               // 分類列表組件
  │  │  └─types
  │  │         Index.ets                      // 數據類型
  │  └─resources
  │─components/personal_homepage/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      BloggerInfomation.ets          // 個人介紹組件
  │  │  │      PersonalHomepage.ets           // 個人中心組件
  │  │  └─types
  │  │         Index.ets                      // 數據類型
  │  └─resources
  │─components/shopping_basket/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      IngredientList.ets             // 用料列表
  │  │  │      PurchaseIngredients.ets        // 用料組件
  │  │  │      ShoppingBasket.ets             // 菜籃子組件
  │  │  └─types
  │  │         Index.ets                      // 數據類型
  │  └─resources
  │─components/upload_recipe/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      UploadRecipe.ets               // 上傳菜譜組件
  │  │  ├─types
  │  │  │      Index.ets                      // 數據類型
  │  │  └─viewmodel
  │  │         UploadRecipeVM.ets             // 上傳菜譜數據模型
  │  └─resources
  │─features/calories/src/main   
  │  ├─ets
  │  │  ├─pages
  │  │  │      CaloriesPage.ets               // 熱量頁面
  │  │  │      DietPlanPage.ets               // 飲食計劃食物列表頁面
  │  │  │      SearchFoodPage.ets             // 食物搜索頁面
  │  │  ├─types
  │  │  │      Index.ets                      // 數據對象
  │  │  └─viewModels
  │  │         CaloriesPageVM.ets             // 熱量頁面數據模型
  │  │         DietPlanPageVM.ets             // 食物列表頁面數據模型
  │  │         SearchFoodPageVM.ets           // 食物搜索頁面數據模型
  │  └─resources
  │─features/classification/src/main   
  │  ├─ets
  │  │  ├─constants
  │  │  │      Enums.ets                      // 枚舉數據
  │  │  ├─pages
  │  │  │      ClassificationPage.ets         // 分類頁面
  │  │  │      DishesPage.ets                 // 菜譜詳情頁面
  │  │  │      ShoppingBasketPage.ets         // 菜籃子頁面
  │  │  ├─types
  │  │  │      Index.ets                      // 菜譜數據對象
  │  │  └─viewModels
  │  │         ClassificationVM.ets           // 分類頁面數據模型
  │  │         DishesVM.ets                   // 菜譜詳情頁面數據模型
  │  └─resources
  │─features/home/src/main   
  │  ├─ets
  │  │  ├─pages
  │  │  │      BloggerProfilePage.ets         // 博主信息頁面
  │  │  │      FollowersPage.ets              // 博主關注頁面
  │  │  │      HomePage.ets                   // 首頁頁面
  │  │  │      SearchPage.ets                 // 搜索頁面
  │  │  ├─types
  │  │  │      Index.ets                      // 首頁數據對象
  │  │  └─viewModels
  │  │         BloggerProfilePageVM.ets       // 博主信息頁面數據模型
  │  │         FollowersPageVM.ets            // 博主關注頁面數據模型
  │  │         HomePageVM.ets                 // 首頁頁面數據模型
  │  │         SearchPageVM.ets               // 搜索頁面數據模型
  │─features/mine/src/main   
  │  ├─ets
  │  │  ├─components
  │  │  │      ConfirmDialogComponent.ets     // 確認彈窗組件
  │  │  │      Recipes.ets                    // 菜譜卡片組件
  │  │  ├─mapper
  │  │  │      Index.ets                      // 數據映射
  │  │  ├─model
  │  │  │      Index.ets                      // 數據類型
  │  │  ├─pages
  │  │  │      BrowsingHistory.ets            // 瀏覽歷史頁面
  │  │  │      MemberCenterPage.ets           // 會員中心頁面
  │  │  │      MinePage.ets                   // 我的頁面
  │  │  │      MyCollection.ets               // 我的收藏頁面
  │  │  │      NoticeCenterPage.ets           // 通知中心頁面
  │  │  │      NoticeDetailPage.ets           // 通知詳情頁面
  │  │  │      PersonalInfo.ets               // 個人信息頁面
  │  │  │      PrivacyPolicyDetailPage.ets    // 用户協議頁面
  │  │  │      QuickLoginPage.ets             // 一鍵登錄頁面
  │  │  │      SettingsPage.ets               // 設置頁面
  │  │  │      SideBarPage.ets                // 服務菜單頁面
  │  │  │      TermsOfServicePage.ets         // 隱私政策頁面
  │  │  │      UploadRecipe.ets               // 上傳菜譜頁面
  │  │  ├─types
  │  │  │      Index.ets                      // 抽象類
  │  │  ├─util
  │  │  │      MockApi.ets                    // 支付mock數據
  │  │  │      OrderInfoUtil.ets              // 支付mock參數工具
  │  │  │      SignUtils.ets                  // 支付mock簽名工具
  │  │  └─viewModels
  │  │         BrowsingHistoryVM.ets          // 瀏覽歷史頁面數據模型
  │  │         MemberCenterPageVM.ets         // 會員中心頁面數據模型
  │  │         MinePageVM.ets                 // 我的頁面數據模型
  │  │         MyCollectionVM.ets             // 我的收藏頁面數據模型
  │  │         MyRecipeVM.ets                 // 我的菜譜頁面數據模型
  │  │         NoticeCenterPageVM.ets         // 通知中心頁面數據模型
  │  │         SettingsPageVM.ets             // 設置頁面數據模型
  │  │         UploadRecipeVM.ets             // 上傳菜譜頁面數據模型
  │  └─resources
  └─products/entry/src/main   
     ├─ets
     │  ├─entryability
     │  │      EntryAbility.ets               // 應用程序入口
     │  ├─entryformability
     │  │      EntryFormAbility.ets           // 卡片程序入口
     │  ├─pages
     │  │      Index.ets                      // 入口頁面
     │  │      LaunchAdPage.ets               // 廣告頁面
     │  │      LaunchPage.ets                 // 開屏頁面
     │  │      MainEntry.ets                  // 主頁面
     │  │      PrivacyPolicyPage.ets          // 隱私協議頁面
     │  ├─types
     │  │      Types.ets                      // 抽象類
     │  ├─viewModels
     │  │      MainEntryVM.ets                // 入口頁面數據
     │  └─widget/pages
     │         WidgetCard.ets                 // 卡片頁面
     └─resources

2. 關鍵代碼解讀

本篇代碼非應用的全量代碼,只包括應用的部分能力的關鍵代碼。

若需獲取全量代碼,請查看模板集成章節。

1)個人信息

  • 華為賬號一鍵登錄
​javascript
// components/aggregated_login/src/main/ets/components/LoginService.ets
// 登錄組件
LoginWithHuaweiIDButton({
    params: {
        style: loginComponentManager.Style.BUTTON_CUSTOM,
        loginType: loginComponentManager.LoginType.QUICK_LOGIN,
        supportDarkMode: true,
        customButtonParams: {
            fontColor: loginComponentManager.FontColor.WHITE,
            backgroundColor: this.loginBtnBgColor,
        },
    },
    controller: this.controller,
});

...

// 登錄方法控制器
controller: loginComponentManager.LoginWithHuaweiIDButtonController =
    new loginComponentManager.LoginWithHuaweiIDButtonController()
// 需要用户同意協議才能完成華為賬號登錄,請先設置協議狀態為NOT_ACCEPTED,當用户同意協議後設置協議狀態為ACCEPTED,才可以完成華為賬號登錄
    .setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)
    .onClickLoginWithHuaweiIDButton((error: BusinessError, response: loginComponentManager.HuaweiIDCredential) => {
    // 處理用户點擊一鍵登錄按鈕邏輯,灰度傳入undefined模擬流程,應用申請權限後,傳入error
    this.handleLoginWithHuaweiIDButton(undefined, response);
});

...

// 處理點擊一鍵登錄後的方法
handleLoginWithHuaweiIDButton(error: BusinessError | undefined,
                              response: loginComponentManager.HuaweiIDCredential) {
    this.enableStatus = false;
    // if部分內容配置好可用的調試證書和client_id後再放開
    if (error) {
        Logger.error(this.domainId, this.logTag,
                     `Failed to click LoginWithHuaweiIDButton. Code is ${error.code}, message is ${error.message}`);
        this.error = error;
        if (error.code === LoginErrorCode.ERROR_CODE_NETWORK_ERROR) {
            AlertDialog.show(
                {
                    message: 'No Internet connection. Check your network settings. ',
                    offset: { dx: 0, dy: -12 },
                    alignment: DialogAlignment.Bottom,
                    autoCancel: false,
                    confirm: {
                        value: 'OK',
                        action: () => {
                        },
                    },
                },
            );
        } else if (error.code === LoginErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED) {
            // 未同意協議,彈出協議彈框,推薦使用該回調方式
            this.agreementDialog.open();
            this.customerDiaLogOpen = true;
        } else if (error.code === LoginErrorCode.ERROR_CODE_LOGIN_OUT) {
            // 華為賬號未登錄提示
            this.showToast($r('app.string.not_login_in'));
        } else if (error.code === LoginErrorCode.ERROR_CODE_NOT_SUPPORTED) {
            // 賬號不支持該scopes或permissions提示
            this.showToast($r('app.string.scope_not_supported'));
        } else if (error.code === LoginErrorCode.ERROR_CODE_NOT_REQUIRED_SCOPE_OR_PERMISSION) {
            // 應用沒有申請scope權限
            this.showToast($r('app.string.app_not_required_scopes_or_permissions'));
        } else {
            // 其他提示系統或服務異常
            this.showToast($r('app.string.service_error'));
        }
        this.enableStatus = true;
        return;
    }
    try {
        if (this.isSelected) {
            // 配置好可用的調試證書和client_id後需要處理response
            Logger.info(this.domainId, this.logTag, 'Succeed in clicking LoginWithHuaweiIDButton.');
            if (this.response.idToken !== undefined) {
                this.response = response;
                // 模擬登錄成功後回調
                this.loginFinishedCb(true, this.unionID)
            }
            // 模擬登錄成功後回調
            this.loginFinishedCb(false)
        } else {
            this.agreementDialog.open();
            this.customerDiaLogOpen = true;
        }
    } catch (e) {
        Logger.info(this.domainId, this.logTag,
                    `Failed to LoginWithHuaweiIDButton, errCode: ${e.code}, errMessage: ${e.message}`);
        AlertDialog.show(
            {
                message: $r('app.string.service_error'),
                offset: { dx: 0, dy: -12 },
                alignment: DialogAlignment.Bottom,
                autoCancel: false,
                confirm: {
                    value: 'OK',
                    action: () => {
                    },
                },
            },
        );
    } finally {
        this.enableStatus = true;
    }
}

2)分類搜索

  • 分類列表
​javascript
// components/link_category/src/main/ets/components/LinkCategory.ets
// 列表頁
Row() {
    List({ space: 8, scroller: this.titleItemScroller }) {
        ForEach(this.recipeCategoryList, (item: RecipeCategory, index: number) => {
            ListItem() {
                this.leftListBuilder(item.name, index)
            }
        }, (item: RecipeCategory, index: number) => item.name + index)
    }
    .width(92)
    .height('100%')
    .backgroundColor('#F1F3F5')
    .listDirection(Axis.Vertical) // 排列方向
    .scrollBar(BarState.Off)
    .contentStartOffset(12)
    .contentEndOffset(12)

    List({ space: 12, scroller: this.scroller }) {
        ForEach(this.recipeCategoryList, (item: RecipeCategory) => {
            ListItemGroup({
                header: this.listTitleBuilder(item.name),
                space: 12,
            }) {
                ListItem() {
                    Grid() {
                        ForEach(item.recipeList, (listItem: RecipeBriefInfo) => {
                            GridItem() {
                                Column() {
                                    Image($r(`app.media.${listItem.thumbnail}`)).width(76).height(76).borderRadius(8)
                                    Text(listItem.title)
                                        .fontSize(14)
                                        .fontWeight(FontWeight.Medium)
                                        .fontColor($r('sys.color.font_primary'))
                                        .textAlign(TextAlign.Center)
                                        .constraintSize({ maxWidth: 76 })
                                        .maxLines(2)
                                        .margin({ top: 4 })
                                        .textOverflow({ overflow: TextOverflow.Ellipsis })
                                }
                            }.onClick(() => {
                                this.onRecipeClick(listItem)
                            })

                        }, (listItem: RecipeBriefInfo) => `${item.id}${listItem.id}`)
                    }
                    .rowsGap(8)
                    .columnsGap(8)
                    .columnsTemplate('1fr 1fr 1fr')

                }

            }
        }, (item: RecipeCategory) => item.id.toString())
    }
    .layoutWeight(1)
    .height('100%')
    .margin({ left: 8, right: 16 })
    .scrollBar(BarState.Off)
    .sticky(StickyStyle.None)
    .contentStartOffset(12)
    .contentEndOffset(12)
    .onScrollIndex((start: number) => this.currentIndexChangeAction(start, false))
}.layoutWeight(1)

...

// 下標索引處理
currentIndexChangeAction(index: number, isClassify: boolean): void {
    if (this.currentIndex !== index) {
        this.changeCurrentIndex(index);
        if (isClassify) {
            this.scroller.scrollToIndex(index);
        } else {
            this.titleItemScroller.scrollToIndex(index);
        }
    }
}

3)熱量計算

  • 環形圖
javascript
// commons/lib_common/src/main/ets/utils/LoginUtils.ets
// 環形組件
Progress({ value: this.todayCalories, total: 2000, type: ProgressType.Ring })
            .width(176).style({ strokeWidth: 20 })
            .color(this.vm.gradientColor)

...

// components/calorie_calculation/src/main/ets/viewModels/CaloriesSummaryVM.ets
// 漸變色設置
gradientColor: LinearGradient =
    new LinearGradient([{ color: '#C6F093', offset: 0.25 }, { color: '#83CE26', offset: 0.5 },
                        { color: '#88DB23', offset: 0.85 }, { color: '#88DB24', offset: 1.0 }])
  • 柱狀圖
javascript
// components/calorie_calculation/src/main/ets/components/BarChart.ets
// 柱狀圖參數設置
this.name = this.xData[this.xData.length - 1]
this.rate = this.seriesData[this.seriesData.length - 1]
// Step1:必須:初始化圖表配置構建類
this.model = new BarChartModel();

// Step2:配置圖表指定樣式,各部件間沒有先後之分

// 為圖表添加數據選擇的監聽器
this.model.setOnChartValueSelectedListener(this.valueSelectedListener);
// 獲取圖表描述部件,設置圖表描述部件不可用,即圖表不進行繪製描述部件
let description: Description | null = this.model.getDescription()
if (description) {
    description.setEnabled(false);
}

// 獲取圖表圖例部件,設置圖表圖例部件不可用
let legend: Legend | null = this.model.getLegend();
if (legend) {
    legend.setEnabled(false);
}

// 設置圖表數據最大的繪製數,如果超過該數值,則不進行繪製圖表的數值標籤
this.model.setMaxVisibleValueCount(7);

// 為左Y軸設置LimitLine,可設置限制線的寬度,線段樣式,限制標籤的位置,標籤字體大小等
this.limitLine1 = new LimitLine(120, 'Upper Limit');
this.limitLine1.setLineWidth(4);
//設置虛線樣式
this.limitLine1.enableDashedLine(10, 10, 0);
//設置標籤位置
this.limitLine1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
this.limitLine1.setTextSize(10);

this.limitLine2 = new LimitLine(50, 'Lower Limit');
this.limitLine2.setLineWidth(4);
this.limitLine2.enableDashedLine(10, 10, 0);
this.limitLine2.setLineColor(Color.Yellow);
this.limitLine2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
this.limitLine2.setTextSize(10);

// 設置圖表左Y軸信息
this.leftAxis = this.model.getAxisLeft();
if (this.leftAxis) {
    //設置繪製標籤個數
    this.leftAxis.setLabelCount(7, false);
    //設置標籤位置
    this.leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART)
    //設置距離頂部距離
    this.leftAxis.setSpaceTop(15);
    //設置最小值
    this.leftAxis.setAxisMinimum(0);
    //設置最大值
    this.leftAxis.setAxisMaximum(2000);
    this.leftAxis.setGridDashedLine({ dash: [2, 2, 0], offset: 0 })
    this.leftAxis.setTextColor('#E6000000')
    this.leftAxis.setTextSize(12)
}

// 設置圖表右Y軸信息
this.rightAxis = this.model.getAxisRight();
if (this.rightAxis) {
    this.rightAxis.setEnabled(false);
}

class YAxisValueFormatter implements IAxisValueFormatter {
    getFormattedValue(value: number, axis: AxisBase): string {
        //將原本存在的對應的value轉換成需要的字符串
        return value.toString();
    }
}

this.leftAxis?.setValueFormatter(new YAxisValueFormatter())

// 設置X軸信息
this.xAxis = this.model.getXAxis();
if (this.xAxis) {
    this.xAxis.setPosition(XAxisPosition.BOTTOM);
    this.xAxis.setDrawGridLines(false);
    this.xAxis.setGranularity(1);
    this.xAxis.setLabelCount(this.xData.length);
    this.xAxis.setTextColor('#E6000000')
    this.xAxis.setTextSize(12)
}

class XAxisValueFormatter implements IAxisValueFormatter {
    data: string[] = []

    constructor(data: string[]) {
        this.data = data
    }

    getFormattedValue(value: number, axis: AxisBase): string {
        //將原本存在的對應的value轉換成需要的字符串
        let day = new Date().getDay() - 1
        if (day === value) {
            return '今日'
        }
        return xMap[value];
    }
}

this.xAxis?.setValueFormatter(new XAxisValueFormatter(this.xData))
// 生成圖表數據
let barData: BarData = this.getBarData();
// 將數據與圖表配置類綁定
this.model.setData(barData);
// 設置圖表最大的X軸顯示範圍,如不設置,則默認顯示全部數據
this.model.setVisibleXRangeMaximum(20);

...

// 柱狀圖組件
BarChart({ model: this.model }).width('100%').height(190)

3. 模板集成

本模板提供了兩種代碼集成方式,供開發者自由選用。

1)整體集成(下載模板)

開發者可以選擇直接基於模板工程開發自己的應用工程。

  • 模板代碼獲取:
    • 通過IDE插件創建模板工程,開發指導。
    • 通過生態市場下載源碼, 下載模板。
    • 通過開源倉訪問源碼,倉庫地址。
  • 打開模板工程,根據README説明中的快速入門章節,將自己的應用信息配置在模板工程內,即可運行並查看模板效果。

  • 對接開發者自己的服務器接口,轉換數據結構,展示真實的雲側數據。

commons/lib_common/src/main/ets/httprequest/HttpRequestApi.ets文件中的mock接口替換為真實的服務器接口。

commons/lib_common/src/main/ets/httprequest/HttpRequest.ets文件中將雲側開發者自定義的數據結構轉換為端側數據結構。

根據自己的業務內容修改模板,進行定製化開發。

2)按需集成

若開發者已搭建好自己的應用工程,但暫未實現其中的部分場景能力,可以選擇取用其中的業務組件,集成在自己的工程中。

  • 組件代碼獲取:
    • 通過IDE插件下載組件源碼。開發指導
    • 通過生態市場下載組件源碼。 下載地址
  • 下載組件源碼,根據README中的説明,將組件包配置在自己的工程中。

  • 根據API參考和示例代碼,將組件集成在自己的對應場景中。

以上是第四期“餐飲行業-美食菜譜”行業優秀案例的內容,更多行業敬請期待~

歡迎下載使用行業模板“點擊下載”,若您有體驗和開發問題,或者迫不及待想了解XX行業的優秀案例,歡迎在評論區留言,小編會快馬加鞭為您解答~

同時誠邀您添加下方二維碼加入“組件模板活動社羣”,精彩上新&活動不錯過!

👉 本系列持續更新,歡迎點擊帖子末尾左下角收藏本帖!

期數

帖子

鏈接

第1期

HarmonyOS官方模板優秀案例 | 便捷生活行業 · 購物中心

點擊查看

第2期

HarmonyOS官方模板優秀案例 | 新聞行業 · 綜合新聞

點擊查看

第3期

HarmonyOS官方模板優秀案例 | 教育行業 · 教育備考

點擊查看

第4期

HarmonyOS官方模板優秀案例 | 餐飲行業 · 美食菜譜

點擊查看

第5期

HarmonyOS官方模板優秀案例 | 工具行業 · 日曆應用

點擊查看

第6期

小編加急整理中,敬請期待

 

👉 HarmonyOS組件模板相關推薦

  • 【活動ing】HarmonyOS組件/模板集成創新活動,報名時間截止2025年8月30日,點擊查看
  • 鴻蒙應用開發者激勵計劃2025,點擊查看
user avatar MiddleByPass 頭像 hubert-style 頭像
點贊 2 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.