首页 > 其他分享 >基于 HarmonyOS 5.0 的美食抽签应用开发实践

基于 HarmonyOS 5.0 的美食抽签应用开发实践

时间:2025-01-12 10:33:24浏览次数:3  
标签:5.0 ets string food 抽签 number private HarmonyOS 美食

基于 HarmonyOS 5.0 的美食抽签应用开发实践

前言

本文记录了一个基于 HarmonyOS 5.0 开发的美食抽签应用实践经验。这是一个解决"吃什么"日常困扰的应用,具有以下特点:

  1. 核心功能

    • 支持早中晚餐分类管理
    • 提供随机抽签选择功能
    • 记录历史抽签数据
    • 展示数据统计分析
  2. 交互设计

    • 流畅的抽签动画效果
    • 精美的食物图标展示
    • 符合直觉的手势操作
    • 清晰的数据可视化
  3. 技术特点

    • 采用 Stage 模型的单 Ability 架构
    • 使用 ArkTS 声明式 UI 开发
    • 基于首选项的数据持久化
    • 支持深浅色主题切换
  4. 项目规范

    • 遵循 TypeScript 开发规范
    • 采用组件化开发方案
    • 统一的错误处理机制
    • 规范的代码组织结构

功能模块

1. 抽签模块

  • 支持按餐点类型抽签
  • 提供抽签动画效果
  • 记录抽签历史
  • 展示抽签结果

2. 管理模块

  • 食物分类管理
  • 自定义添加食物
  • 食物图标选择
  • 批量导入导出

3. 统计模块

  • 展示抽签频率统计
  • 提供历史记录查询
  • 数据可视化图表
  • 使用习惯分析

开发环境

  • HarmonyOS SDK: 5.0.0
  • DevEco Studio: 5.0
  • Node.js: 18.12.0
  • ohpm: 1.0.0

技术栈

  • 开发框架:ArkTS + HarmonyOS 5.0
  • UI 框架:ArkUI 5.0
  • 状态管理:@State、@Link、@Prop、@Provide/@Consume
  • 数据持久化:Data Preferences
  • 动画系统:ArkTS Animation API

项目结构

entry/src/main/ets/
├── pages/                 # 页面目录
│   ├── Index.ets         # 主页面
│   └── tabs/             # 标签页
│       ├── DrawPage.ets  # 抽签页面
│       ├── ManagePage.ets# 管理页面
│       └── StatsPage.ets # 统计页面
├── services/             # 服务层
│   ├── FoodListService.ets  # 食物列表服务
│   └── FoodDataService.ets  # 数据服务
├── components/           # 组件目录
│   ├── FoodCard.ets     # 食物卡片组件
│   └── StatChart.ets    # 统计图表组件
├── common/              # 公共目录
│   ├── constants/       # 常量定义
│   └── utils/          # 工具函数
└── models/             # 数据模型
    └── FoodModel.ets   # 食物数据模型

数据结构设计

// 食物数据模型
interface FoodItem {
    id: string // 唯一标识
    name: string // 食物名称
    type: MealType // 餐点类型
    icon?: string // 食物图标
    createTime: number // 创建时间
}

// 餐点类型枚举
enum MealType {
    BREAKFAST = 'breakfast',
    LUNCH = 'lunch',
    DINNER = 'dinner',
}

// 抽签记录
interface DrawRecord {
    id: string // 记录ID
    foodId: string // 食物ID
    time: number // 抽签时间
    type: MealType // 餐点类型
}

// 统计数据
interface FoodStat {
    foodId: string // 食物ID
    count: number // 抽签次数
    lastTime: number // 最后抽签时间
}

核心功能实现

1. Stage 模型应用

import AbilityConstant from '@ohos.app.ability.AbilityConstant'
import UIAbility from '@ohos.app.ability.UIAbility'
import window from '@ohos.window'

export default class EntryAbility extends UIAbility {
    onCreate(want: Want) {
        // 应用初始化
    }

    onWindowStageCreate(windowStage: window.WindowStage) {
        // 加载主页面
        windowStage.loadContent('pages/Index', (err, data) => {
            if (err.code) {
                console.error('Failed to load content', err.code)
                return
            }
        })
    }
}

2. 数据服务实现

export class FoodDataService {
    private static instance: FoodDataService
    private preferences: data_preferences.Preferences | null = null
    private readonly STORE_NAME: string = 'FoodPreferences'

    public static getInstance(): FoodDataService {
        if (!FoodDataService.instance) {
            FoodDataService.instance = new FoodDataService()
        }
        return FoodDataService.instance
    }

    public async getFoodsByType(type: MealType): Promise<FoodItem[]> {
        const foods = await this.getAllFoods()
        return foods.filter((item) => item.type === type)
    }

    private async ensureInitialized(): Promise<void> {
        if (!this.preferences) {
            await this.init()
        }
    }
}

3. 自定义组件封装

@Component
struct FoodCard {
  @Prop food: FoodItem
  @State private isPressed: boolean = false
  @Consume('themeData') theme: Theme

  build() {
    Row() {
      Text(this.food.icon)
        .fontSize(24)
      Text(this.food.name)
        .fontSize(16)
        .fontColor(this.theme.textColor)
    }
    .width('100%')
    .padding(16)
    .backgroundColor(this.isPressed ?
      this.theme.pressedColor :
      this.theme.backgroundColor)
    .borderRadius(8)
    .stateStyles({
      pressed: {
        transform: { scale: 0.98 },
        opacity: 0.8
      }
    })
  }
}

4. 性能优化实践

  1. 列表性能优化:
@Component
struct OptimizedList {
  @State private foodList: FoodItem[] = []

  build() {
    List({ space: 12 }) {
      LazyForEach(this.foodList,
        (food: FoodItem) => this.ListItem(food),
        (food: FoodItem) => food.id
      )
    }
    .onScrollIndex((first: number, last: number) => {
      this.handleVisibleItemsChange(first, last)
    })
  }

  @Builder
  private ListItem(food: FoodItem) {
    Row() {
      Text(food.icon)
        .fontSize(24)
      Text(food.name)
        .fontSize(16)
    }
    .width('100%')
    .padding(16)
  }
}
  1. 启动优化:
aboutToAppear() {
  // 延迟加载非关键资源
  setTimeout(() => {
    this.loadNonCriticalResources()
  }, 0)

  // 并行加载数据
  Promise.all([
    this.loadFoodList(),
    this.loadUserPreferences(),
    this.loadThemeSettings()
  ]).catch(err => {
    console.error('Failed to load initial data:', err)
  })
}

5. 错误处理

class ErrorHandler {
    static handle(error: Error, context: string) {
        Logger.error(`[${context}]`, error)

        if (error instanceof NetworkError) {
            this.showToast('网络连接失败,请检查网络设置')
        } else if (error instanceof DataError) {
            this.showToast('数据加载失败,请稍后重试')
        }
    }

    private static showToast(message: string) {
        promptAction.showToast({
            message: message,
            duration: 3000,
            bottom: '100vp',
        })
    }
}

6. 主题系统实现

// 主题配置
interface ThemeConfig {
  colorMode: 'light' | 'dark'
  primaryColor: string
  backgroundColor: string
  textColor: string
  cardColor: string
}

@Component
struct ThemeProvider {
  @State themeConfig: ThemeConfig = defaultTheme

  @Builder
  renderContent() {
    Column() {
      // 页面内容
    }
    .backgroundColor(this.themeConfig.backgroundColor)
    .width('100%')
    .height('100%')
  }

  build() {
    Column() {
      this.renderContent()
    }
  }
}

7. 动画效果实现

@Component
struct DrawAnimation {
  @State private rotateAngle: number = 0
  @State private scale: number = 1

  // 抽签动画
  private startAnimation() {
    animateTo({
      duration: 1000,
      curve: Curve.EaseInOut,
      onFinish: () => {
        this.handleAnimationComplete()
      }
    }, () => {
      this.rotateAngle = 360
      this.scale = 1.2
    })
  }

  build() {
    Stack() {
      // 动画内容
    }
    .rotate({ x: 0, y: 1, z: 0, angle: this.rotateAngle })
    .scale({ x: this.scale, y: this.scale })
  }
}

8. 统计图表实现

@Component
struct StatisticsChart {
  @State private data: FoodStat[] = []
  private readonly chartWidth: number = 300
  private readonly chartHeight: number = 200

  private calculateBarHeight(count: number): number {
    const maxCount = Math.max(...this.data.map(item => item.count))
    return maxCount === 0 ? 0 : (count / maxCount) * this.chartHeight
  }

  build() {
    Column() {
      Row() {
        ForEach(this.data, (item: FoodStat) => {
          Column() {
            Text(item.count.toString())
              .fontSize(12)
            Column()
              .width(20)
              .height(this.calculateBarHeight(item.count))
              .backgroundColor('#FF4B4B')
            Text(item.name)
              .fontSize(12)
          }
        })
      }
      .width(this.chartWidth)
      .height(this.chartHeight)
    }
  }
}

实现要点

  1. 数据管理

    • 使用单例模式管理全局数据
    • 采用 Data Preferences 实现数据持久化
    • 实现类型安全的数据操作
  2. UI 实现

    • 基于 ArkTS 声明式 UI 开发
    • 自定义组件封装复用
    • 响应式布局适配
  3. 性能优化

    • 使用 LazyForEach 实现虚拟列表
    • 延迟加载非关键资源
    • 优化动画性能
  4. 工程规范

    • 统一的错误处理机制
    • 规范的代码组织结构
    • 完善的类型定义

开发心得

  1. Stage 模型简化了应用架构设计
  2. ArkTS 提供了优秀的开发体验
  3. 组件化开发提高了代码复用率
  4. 性能优化需要注意细节

参考资源

  1. HarmonyOS 应用开发文档

关于作者

专注 HarmonyOS 应用开发,欢迎交流讨论:

  • gitee:https://gitee.com/zhaoyl1/what-to-eat-meta-service/settings#index

标签:5.0,ets,string,food,抽签,number,private,HarmonyOS,美食
From: https://blog.csdn.net/qq_36597625/article/details/144983286

相关文章

  • 【HarmonyOS Next NAPI 深度探索1】Node.js 和 CC++ 原生扩展简介
    【HarmonyOSNextNAPI深度探索1】Node.js和CC++原生扩展简介如果你用过Node.js,应该知道它强大的地方在于能处理各种场景,速度还很快。但你有没有想过,Node.js的速度秘密是什么?今天我们来聊聊其中一个幕后英雄——原生扩展,特别是如何通过C/C++把JavaScript的能力进......
  • 2025.01.10 杂题记录
    2025.01.10杂题记录CF1998E2这题是求能否吃完,而不是最多吃多少个。首先如果\(x=n\),那么是经典问题,每次往左右二分一个位置扩展,每次扩展两次和都会翻倍,复杂度就是\(O(n\logn\logV)\)。我们考虑每个起始点对每个\(f(i)\)的贡献。我们每次应当优先往左扩展,如果扩展不了,往......
  • 美食推荐商城(代码+数据库+LW)
    摘 要现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本美食推荐商城就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达......
  • 笔记 harmonyOS 页面跳转及传递参数
            页面之间的导航可以通过页面路由router模块来完成。页面路由模块根据页面的URL找到目标页面,从而实现跳转。通过页面路由模块,可以使用不同的URL访问不同的页面,包括跳转到Ability内的指定页面、用Ability内的某个页面替换当前页面、返回上一个页面或指定的页面。......
  • 【AIGC-ChatGPT进阶提示词指令】AI美食助手的设计与实现:Lisp风格系统提示词分析
    引言在人工智能助手的应用领域中,美食烹饪是一个既专业又贴近生活的方向。本文将详细分析一个基于Lisp风格编写的美食助手系统提示词,探讨其结构设计、功能实现以及实际应用效果。提出你的菜系,为你分析,并生成图片卡片提示词在最下方效果图系统架构设计核心角色定......
  • 【HarmonyOS NEXT】一多开发介绍(断点、媒体查询、栅格布局)
    断点鸿蒙提供断点以应用窗口宽度为切入点,将应用窗口在宽度维度上分成了几个不同的区间即不同的断点,不同设备会进入到不同的断点区间,在不同的区间下,我们可以可根据需要实现不同的页面布局效果。具体的断点对应的设备尺寸如下所示。断点名称取值范围(vp)xs[0,320)sm[320,600)......
  • HTML+CSS+JS制作中华传统美食主题网站(内附源码,含5个页面)
    一、作品介绍HTML+CSS+JS制作一个中华传统文化主题网站,包含首页、菜系页、食材页、名厨页、美食故事页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。二、页面结构1.顶部横幅导航区包含网站Logo、搜索栏、主导航菜单(首页、菜系分类、美食故......
  • 基于数据可视化+django豆果美食推荐系统
    目录项目介绍系统操作流程 系统架构设计演示视频系统功能实现代码实现 推荐项目项目开发总结为什么选择我 源码获取博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者......
  • Xinstall HarmonyOS SDK:助力鸿蒙生态,开启智能应用新篇章!应用集成即享10天专业版免费使
    10月22日,华为正式发布了HarmonyOSNEXT原生鸿蒙系统。自问世以来,凭借其独特的分布式特性与创新交互,在智能设备领域掀起了一场革新风暴,吸引着无数开发者投身其中,探索无限可能。目前,已有超1万个应用和元服务上架HarmonyOSNEXT应用市场,华为开发者联盟注册开发者数量已增长......
  • zabbix5.0版本 (用脚本自定义监控项+监控MySQL状态信息)
    目录1.用脚本自定义监控项(1)编写脚本进行取值(2)修改zabbix客户端配置文件(3)zabbix创建模板及监控项(4)关联至被监控主机2.监控MySQl状态信息(1)使用脚本定义监控项(2)服务端创建MySQL监控模板(3)添加触发器(4)配置图形(5)关联至被监控主机(6)测试并查看数据3.自定义监控项以及监控......