HarmonyOS ArkUI入门—HarmonyOS ArkUI来开发一个健康饮食应用

2024-03-16 00:44

本文主要是介绍HarmonyOS ArkUI入门—HarmonyOS ArkUI来开发一个健康饮食应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文演示如果在DevEco Studio 3里面,用HarmonyOS的ArkUI来开发一个健康饮食应用。体验HarmonyOS 3最新API 9!

获取HarmonyOS应用

HarmonyOS的ArkUI来开发一个健康饮食的ArkUI程序“ArkUIHealthyDiet”,基础代码已经有了[1],个人只需要在基础代码上稍作修改,就能运行了。

通过DevEco Studio 3导入应用

有关DevEco Studio 3的安装配置,可以参考前文《玩转HarmonyOS 3必装DevEco Studio 3,注意避弹[2]》这里就不在赘述。

首选是打开DevEco Studio 3,可以看到如下界面。

点击“Open Project”来导入我们实行装备好的ArkUI程序“ArkUIHealthyDiet”。

导入程序之后,就能在该程序基础上进行代码开发、运行。

通过DevEco Studio 3创建应用

如果想从0开始学习ArkUI,体验完整的HarmonyOS的开发过程,那么建议跟随本文一起来开启ArkUI开发之旅吧。

首选是打开DevEco Studio 3,可以看到如下界面。

在这里插入图片描述


点击“Create Project”来创建ArkUI程序“ArkUIHealthyDiet”。

选择模板

选择空模板Empty Ability,点击“Next”执行下一步。

在这里插入图片描述

配置项目

配置项目信息,重要是以下圈中部分。其他配置按照默认配置即可。点击“Finish”执行下一步。

在这里插入图片描述

运行HarmonyOS应用

打开Device Manager

在这里插入图片描述

在这里插入图片描述

登入华为账号

点击“Sign In”登入个人注册的华为账号。如果没有,则参考本文最后的链接进行注册。

在这里插入图片描述


启动远程模拟器

在这里插入图片描述

运行应用

点击下命的三角形按钮以启动应用

在这里插入图片描述


应用运行效果图如下。

在这里插入图片描述

完善应用

接下来是进入正题,开始我们的健康饮食应用的核心功能的开发了。

构建食物数据模型

要创建食物数据模型来统一存储和管理食物的数据。食物的信息包括:食物名称、卡路里、蛋白质、脂肪、碳水和维生素C等。

在这里插入图片描述


在ets目录下新建model文件夹,用于存放数据模型文件。

在这里插入图片描述


在model目录下创建DataModels.ets,用于存放数据模型。

定义食物数据的存储模型FoodInfo和枚举变量CategoryId,FoodData类包含食物id、名称(name)、分类(category)、图片(image)、热量(calories)、蛋白质(protein)、脂肪(fat)、碳水(carbohydrates)和维生素C(vitaminC)属性等等。

export enum CategoryId {Fruit = 0,Vegetable,Nut,Seafood,Dessert
}
export type FoodInfo = {id: numberletter: stringname: string | Resourceimage: ResourcecategoryId: CategoryIdcalories: numberprotein: numberfat: numbercarbohydrates: numbervitaminC: number
}

创建食物资源数据。在ets目录下创建mock文件夹,并在mock文件夹下创建MockData.ets。在MockData.ets中声明食物成分数组代码如下:

import { FoodInfo, CategoryId} from '../model/DataModels'
// 构造数据的mock数据
export let mockFoods: Array<FoodInfo> = [{id: 0,letter: 'Kiwi',name: $r('app.string.food_name_kiwi'),image: $r('app.media.kiwi'),categoryId: CategoryId.Fruit,calories: 61,protein: 0.8,fat: 0.6,carbohydrates: 14.5,vitaminC: 62},{id: 1,letter: 'Walnut',name: $r('app.string.food_name_walnut'),image: $r('app.media.walnut'),categoryId: CategoryId.Nut,calories: 646,protein: 14.9,fat: 58.8,carbohydrates: 19.1,vitaminC: 1.0},{id: 2,letter: 'Cucumber',name: $r('app.string.food_name_cucumber'),image: $r('app.media.cucumber'),categoryId: CategoryId.Vegetable,calories: 16,protein: 0.8,fat: 0.2,carbohydrates: 2.9,vitaminC: 9.0},{id: 3,letter: 'Blueberry',name: $r('app.string.food_name_blueberry'),image: $r('app.media.blueberry'),categoryId: CategoryId.Fruit,calories: 57,protein: 0.7,fat: 0.3,carbohydrates: 14.5,vitaminC: 9.7},{id: 4,letter: 'Crab',name: $r('app.string.food_name_crab'),image: $r('app.media.crab'),categoryId: CategoryId.Seafood,calories: 97,protein: 19,fat: 1.5,carbohydrates: 0,vitaminC: 7.6},{id: 5,letter: 'IceCream',name: $r('app.string.food_name_ice_cream'),image: $r('app.media.icecream'),categoryId: CategoryId.Dessert,calories: 150,protein: 3.5,fat: 11,carbohydrates: 24,vitaminC: 0.6},{id: 6,letter: 'Onion',name: $r('app.string.food_name_onion'),image: $r('app.media.onion'),categoryId: CategoryId.Vegetable,calories: 40,protein: 1.1,fat: 0.2,carbohydrates: 9,vitaminC: 8.0},{id: 7,letter: 'Mushroom',name: $r('app.string.food_name_mushroom'),image: $r('app.media.mushroom'),categoryId: CategoryId.Vegetable,calories: 20,protein: 3.1,fat: 0.3,carbohydrates: 3.3,vitaminC: 206},{id: 8,letter: 'Tomato',name: $r('app.string.food_name_tomato'),image: $r('app.media.tomato'),categoryId: CategoryId.Vegetable,calories: 15,protein: 0.9,fat: 0.2,carbohydrates: 3.3,vitaminC: 14.0},{id: 9,letter: 'Pitaya',name: $r('app.string.food_name_pitaya'),image: $r('app.media.pitaya'),categoryId: CategoryId.Fruit,calories: 55,protein: 1.1,fat: 0.2,carbohydrates: 13.3,vitaminC: 3.0},{id: 10,letter: 'Avocado',name: $r('app.string.food_name_avocado'),image: $r('app.media.avocado'),categoryId: CategoryId.Fruit,calories: 171,protein: 2.0,fat: 15.3,carbohydrates: 7.4,vitaminC: 8.0},{id: 11,letter: 'Strawberry',name: $r('app.string.food_name_strawberry'),image: $r('app.media.strawberry'),categoryId: CategoryId.Fruit,calories: 32,protein: 1.0,fat: 0.2,carbohydrates: 7.1,vitaminC: 47.0}
]

name需要考虑国际化,因此,该值是存储在string.json文件中。

在这里插入图片描述


image所引用的食物图片资源,放置在resources >base> media目录下。

在这里插入图片描述


在model目录下创建DataUtil.ets,用于加载健康饮食应用的数据。

import { FoodInfo } from './DataModels'
import { mockFoods } from '../mock/MockData'
export function getFoods(): Array<FoodInfo> {return mockFoods
}

已完成好健康饮食应用的数据资源准备,接下来将通过加载这些数据来创建食物列表页面。

构建食物列表List布局

使用List组件和ForEach循环渲染,构建食物列表布局。

修改pages目录下的Index.ets文件,新建FoodList组件作为页面入口组件,FoodListItem为其子组件。List组件是列表组件,适用于重复同类数据的展示,其子组件为ListItem,适用于展示列表中的单元。

import { FoodInfo } from '../model/DataModels'
import { getFoods } from '../model/DataUtil'
@Component
struct FoodListItem {private foodItem: FoodInfobuild() {Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {Image(this.foodItem.image).objectFit(ImageFit.Contain).height(40).width(40).margin({ right: 16 })Text(this.foodItem.name).fontSize(14).flexGrow(1)Text(this.foodItem.calories + ' kcal').fontSize(14)}.height(64).margin({ right: 24, left: 32 })}
}
@Entry
@Component
struct FoodList {private foodItems: FoodInfo[] = getFoods()build() {Column() {Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {Text('Food List').fontSize(20).margin({ left: 20 })}.height('7%').backgroundColor('#FFf1f3f5')List() {ForEach(this.foodItems, item => {ListItem() {FoodListItem({ foodItem: item })}}, item => item.id.toString())}.height('93%')}}
}

运行应用,可以看到列表的效果如下。

在这里插入图片描述

构建食物详情页面

在pages目录下,创建FoodDetail.ets文件,FoodDetail页面的食物信息都是直接声明的常量,现在要用传递来的FoodData数据来对其进行重新赋值。整体的FoodDetail.ets代码如下。

import router from '@ohos.router'
import { FoodInfo } from '../model/DataModels'
@Component
struct PageTitle {build() {Flex({ alignItems: ItemAlign.Start }) {Image($r('app.media.back')).width(21.8).height(19.6)Text('Food Detail').fontSize(21.8).margin({left: 17.4})}.height(61).backgroundColor('#FFedf2f5').padding({ top: 13, bottom: 15, left: 28.3 }).onClick(() => {router.back()})}
}
@Component
struct FoodImageDisplay {private foodItem: FoodInfobuild() {Stack({ alignContent: Alignment.BottomStart }) {Image(this.foodItem.image).objectFit(ImageFit.Contain)Text(this.foodItem.name).fontSize(26).fontWeight(500).margin({ left: 26, bottom: 17.4 })}.height(357).backgroundColor('#FFedf2f5')}
}
@Component
struct ContentTable {private foodItem: FoodInfo@Builder IngredientItem(title:string, name: string, value: string) {Flex() {Text(title).fontSize(17.4).fontWeight(FontWeight.Bold).layoutWeight(1)Flex() {Text(name).fontSize(17.4).flexGrow(1)Text(value).fontSize(17.4)}.layoutWeight(2)}}build() {Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) {this.IngredientItem('Calories', 'Calories', this.foodItem.calories + 'kcal')this.IngredientItem('Nutrition', 'Protein', this.foodItem.protein + 'g')this.IngredientItem('', 'Fat', this.foodItem.fat + 'g')this.IngredientItem('', 'Carbohydrates', this.foodItem.carbohydrates + 'g')this.IngredientItem('', 'VitaminC', this.foodItem.vitaminC + 'mg')}.height(280).padding({ top: 30, right: 30, left: 30 })}
}
@Entry
@Component
struct FoodDetail {private foodItem: FoodInfo = router.getParams()[foodInfo]build() {Column() {Stack( { alignContent: Alignment.TopStart }) {FoodImageDisplay({ foodItem: this.foodItem })PageTitle()}ContentTable({ foodItem: this.foodItem })}.alignItems(HorizontalAlign.Center)}
}

上述代码引用了路由Router API的接口,通过在页面上引入router,可以调用router的各种接口,从而实现页面路由的各种操作。调用router.getParams()[foodInfo]来获取到列表页面跳转来时携带的foodData对应的数据。

列表与详情页面的跳转

上述详情页面已经引用了路由Router API,能否接受来自路由的参数。那么相应的,列表页面也需要做相应的调整,来触发路由跳转。点击Index后跳转到FoodDetail页面。在FoodListItem内创建Navigator组件,使其子组件都具有路由功能,目标页面target为’pages/FoodDetail’。

修改Index.ets文件,

@Component
struct FoodListItem {private foodItem: FoodInfobuild() {// 增加路由导航Navigator({ target: 'pages/FoodDetail' }) {Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {Image(this.foodItem.image).objectFit(ImageFit.Contain).height(40).width(40).backgroundColor('#FFf1f3f5').margin({ right: 16 })Text(this.foodItem.name).fontSize(14).flexGrow(1)Text(this.foodItem.calories + ' kcal').fontSize(14)}.height(64)}// 页面间数据传递.params({ foodInfo: this.foodItem }).margin({ right: 24, left:32 })}
}

其中,Navigator为路由容器组件,包装了页面路由的能力,指定页面target后,使其包裹的子组件都具有路由能力。.params方法用于页面间数据传递。

程序运行效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

相关问题

问题1:路由失效

报错如下:

[manifest_router.cpp(GetPagePath)-(0)] [Engine Log] can’t find this page pages/FoodDetail path

解决方案:

main_pages中添加pages/FoodDetail

在这里插入图片描述

最后

随着鸿蒙开发越来越火热,我了解到现在有很多小伙伴想入行鸿蒙,但又不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。我给大家整理了一份实用的鸿蒙(Harmony OS)开发学习手册资料用来跟着学习是非常有利于帮助大家提升鸿蒙开发技术的。

相对于网上那些碎片化的知识内容,这份学习资料的知识点更加系统化,更容易理解和记忆。资料包含了、应用开发导读(ArkTS)、HarmonyOS 概念、如何快速入门、开发基础知识、基于ArkTS 开发、等鸿蒙开发必掌握的核心知识要点,内容包含了(技术知识点。

在这里插入图片描述


希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→《一小时快速认识HarmonyOS》

鸿蒙(Harmony NEXT)最新学习路线

在这里插入图片描述


有了路线图,怎么能没有学习资料呢,小编也准备了几套HarmonyOS NEXT学习视频 内容包含以下联

内容包含:ArkTS、ArkUI、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→《鸿蒙星河版开发教程》

D·TS语法教程

在这里插入图片描述


领取以上完整高清学习视频,请点击→《鸿蒙 (Harmony OS)D·TS语法教程》小编自己整理的部分学习资料(包含有高清视频、开发文档、电子书籍等)

ArkTS基础链接

在这里插入图片描述


领取以上完整高清学习视频,请点击→《鸿蒙HarmonyOS:ArkTS基础链接》小编自己整理的部分学习资料(包含有高清视频、开发文档、电子书籍等)

TypeScript链接

在这里插入图片描述


领取以上完整高清学习视频,请点击→《HarmonyOS;TypeScript链接》小编自己整理的部分学习资料(包含有高清视频、开发文档、电子书籍等)

这篇关于HarmonyOS ArkUI入门—HarmonyOS ArkUI来开发一个健康饮食应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/813797

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本