【中工开发者】鸿蒙商城app
这学期我学习了鸿蒙,想用鸿蒙做一个鸿蒙商城app,来展示一下。
项目环境搭建:
1.开发环境:DevEco Studio
2.开发语言:ArkTS
3.运行环境:Harmony NEXT base1
软件要求:
DevEco Studio 5.0.0 Release
HarmonyOS SDK版本:API version 10
硬件要求:
华为手机或能够顺利运行DevEco Studio上的华为手机模拟器的电脑
1.欢迎界面实现
欢迎界面的实现过程如下:首先,我们创建了一个名为Index的组件,使用Column容器组件构建布局,并在其中添加了空白空间、文本和另一个Column容器。文本内容为“探索”和“购物乐趣”,字体大小为50,颜色为白色,并且加粗。接着,在Column容器中添加了一张图片,图片资源位于resource文件夹下的logo图片素材中。整个欢迎界面的背景采用了渐变色,颜色从#FF8469渐变到#FC4355。为了实现欢迎界面的闪屏变化效果,我们添加了一个透明度变化的动画,使用属性动画实现渐变过渡。在Column组件上添加了opacity属性,并使用state修饰器声明了一个状态变量opacityValue,初始值为0.3。在生命周期函数onPageShow中,我们将opacityValue设置为1,使组件完全显示。动画的duration参数设置为1500ms,iterations参数设置为3次播放。动画完成后,会触发onFinish方法。
@Entry
@Component
struct Index {build() {Column(){Blank()Column(){}.height('100%').width('100%').linearGradient({colors: [["#B3CDE3", 0], // 浅蓝色["#7F8FA6", 0.5], // 中等蓝色["#2C3E50", 1] // 深蓝色]})}}
}

@Entry
@Component
struct LaunchPage {build() {Column() {Blank()Column(){Text('探索').fontSize(50).fontColor(Color.White)Text('购物乐趣').fontSize(50).fontColor(Color.White)}}.height('100%').width('100%').linearGradient({colors: [["#B3CDE3", 0], // 浅蓝色["#7F8FA6", 0.5], // 中等蓝色["#2C3E50", 1] // 深蓝色]})}
}

记得把logo图片放在如下目录里面resource文件夹下面
logo图片素材

import router from '@ohos.router';
@Entry
@Component
struct Index {@State opacityValue: number = 0.3;onPageShow(){this.opacityValue = 1;}build() {Column(){Blank()Column(){Text('探索').fontSize(50).fontColor(Color.White).fontWeight(FontWeight.Bold)Text('购物乐趣').fontSize(50).fontColor(Color.White).fontWeight(FontWeight.Bold)}.alignItems(HorizontalAlign.Start).opacity(this.opacityValue).animation({duration: 1500,iterations:3,onFinish: () => {router.pushUrl({url: '/pages/LaunchPage'});}})Blank()Blank()Image($r('app.media.logo')).width(200)}.margin({top:30}).height('100%').width('100%').linearGradient({colors: [["#B3CDE3", 0], // 浅蓝色["#7F8FA6", 0.5], // 中等蓝色["#2C3E50", 1] // 深蓝色]})}}
效果图如下

到此我们完成了欢迎界面的布局
接下来我们将实现欢迎界面的闪屏变化效果,可以使用属性动画来实现渐变过渡的效果
我们添加一个组件,透明度变化的动画可以使用属性动画来实现渐变过渡的效果,在column组件上添加opacity属性,透明度的变化是一个动态的值,这里我们使用state修饰器声明一个状态变量,状态变量变化会触发UI刷新,默认的透明度设置为0.3,然后在生命周期函数,on page show中设置透明度的值为一让组件完全显示,然后设置animation属性动画的参数duration参数设置动画时长默认值为1000ms,这里我们设置为1500ms,iterations参数设置播放次数默认值播放一次,这里我们设置播放三次,最后添加UNFINISH方法,该方法在动画播放完成时触发
@Entry
@Component
struct Index {@State opacityValue: number = 0.3;onPageShow(){this.opacityValue = 1;}build() {Column(){Blank()Column(){Text('探索').fontSize(50).fontColor(Color.White).fontWeight(FontWeight.Bold)Text('购物乐趣').fontSize(50).fontColor(Color.White).fontWeight(FontWeight.Bold)}.alignItems(HorizontalAlign.Start).opacity(this.opacityValue).animation({duration: 1500,iterations:3,onFinish: () => {}})Blank()Blank()Image($r('app.media.logo')).width(200)}.height('100%').width('100%').linearGradient({colors: [['#FF8469',0],[ '#FC4355',1] ]})}}
现在我们在预览界面查看欢迎界面的最终效果
2.引导页实现

接下来,我们实现引导页。创建launchPage页面


在index页面导入import router from '@ohos.router';

引导页的布局采用垂直方向,使用Column容器组件,并设置宽度和高度。背景同样使用渐变色。
LaunchPage页面
@Entry
@Component
struct LaunchPage {build() {Column() {}.height('100%').width('100%').linearGradient({colors: [["#B3CDE3", 0], // 浅蓝色["#7F8FA6", 0.5], // 中等蓝色["#2C3E50", 1] // 深蓝色]})}
}

引导页创建好后,我们使用页面路由跳转到应用内的指定页面。在欢迎界面中导入路由模块,
import router from '@ohos.router';
并在动画效果结束后调用路由的push url方法,配置跳转选项,并传入引导页的URL。

引导页的功能包括通过左右滑动切换页面,使用Tabs组件实现内容视图的切换。每个页签对应一个TabContent组件。
我们创建了一个banner model对象,包含id、title、subtitle和image属性,并指定了引导页的数据源。在Tabs组件中,我们添加了三个TabContent组件,并通过forEach接口基于数组类型数据进行循环渲染。每个TabContent组件中,我们创建了一个Column组件,设置宽度、高度和内边距,并在其中添加了Text和Image组件,显示标题、内容和图片。我们还创建了一个页码指示器,使用Roll组件渲染页码指示器,同样使用forEach执行循环渲染。最后,当切换到最后一个页签时,显示一个“立即体验”的按钮,点击后跳转到商城首页。在Button组件的点击事件中,我们调用路由的push url方法,传入首页的URL,实现跳转。
LaunchPage页面代码如下
import BannerModel from '../models/BannerModel'
import { router } from '@kit.ArkUI'@Entry
@Component
struct LaunchPage {currentIndex: number = 0@State index: number = 0@State items: BannerModel[] =[{ id:0,title: '甄选推荐',subtitle: '精心挑选,为您呈现',image:'https://img1.wushang.com/pn/wsec-img1/2021/6/9/d8328eef-8552-4d4e-968c-7030836e46f1.jpg?x-oss-process=image/resize,w_800,h_800',},{ id:1,title: '手机专区',subtitle: '手机特惠区,尽享购物惊喜',image: 'https://img.alicdn.com/i2/1114511827/O1CN018TdXCN1PMoOG25L5Q_!!1114511827.jpg',},{ id:2,title: '电脑专区',subtitle: '电脑特区,装备你的数位生活',image: 'https://tse3-mm.cn.bing.net/th/id/OIP-C.nDvymf_rVmMgx0RnuRbwOQHaGM?rs=1&pid=ImgDetMain',}]build() {Column() {Tabs(){ForEach(this.items, (item: BannerModel) => {TabContent(){Column() {Text(item.title).fontSize(50).fontColor(Color.White).fontWeight(FontWeight.Bold)Text(item.subtitle).fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)Blank()Image(item.image).width(300).height(300).objectFit(ImageFit.Contain).interpolation(ImageInterpolation.High)Row({ space: 10}){ForEach(this.items,(item:BannerModel) => {Rect({width: 10,height: 10}).fill(this.currentIndex === item.id ? Color.White : Color.Gray)})}.margin({ top: 30})if (this.currentIndex == this.items.length-1) {Button({ type: ButtonType.Capsule }){Text('立即体验').fontColor(Color.White).fontSize(18)}.width(200).height(50).backgroundColor(Color.Transparent).borderWidth(2).borderColor(Color.Black).borderRadius(6).onClick(() => {router.pushUrl({url: 'pages/HomePage'})}).margin({ top: 50})}}.width('100%').height('100%').padding({ top: 50,left: 50,right: 50})}})}.width('100%').height('100%').onChange((value: number)=>{this.currentIndex = value})}.height('100%').width('100%').linearGradient({colors: [["#B3CDE3", 0], // 浅蓝色["#7F8FA6", 0.5], // 中等蓝色["#2C3E50", 1] // 深蓝色]})}
}
LaunchPage页面预览效果图如下所示



3.首页自定义导航栏选项卡
@Entry
@Component
struct HomePage {@State currentIndex:number = 0private tabsController: TabsController = new TabsController()@BuilderTabBuilder(title:string,image:Resource,selectedImage:Resource,tag:number){
Column(){Image(this.currentIndex === tag?selectedImage:image).size({width: 40, height: 40}).objectFit(ImageFit.Contain).interpolation(ImageInterpolation.High)Text(title).fontSize(14).fontColor(this.currentIndex === tag?Color.Blue:Color.Black)
}.width('100%').height(50).justifyContent(FlexAlign.Center).border({width: {top: 1},color: Color.White}).onClick(()=>{this.currentIndex = tagthis.tabsController.changeIndex(this.currentIndex)})}build() {Column(){Tabs({barPosition:BarPosition.End,controller:this.tabsController}){TabContent(){Text('首页')}.tabBar(this.TabBuilder('首页',$r('app.media.home'),$r('app.media.home_selected'),0))TabContent(){Text('分类')}.tabBar(this.TabBuilder('分类',$r('app.media.sort'),$r('app.media.sort_selected'),0))TabContent(){Text('购物车')}.tabBar(this.TabBuilder('购物车',$r('app.media.cart'),$r('app.media.cart_selected'),0))TabContent(){Text('我的')}.tabBar(this.TabBuilder('我的',$r('app.media.my'),$r('app.media.my_selected'),0))}.width('100%').height('100%').barHeight(80).backgroundColor(Color.White).onChange((index:number)=>{this.currentIndex = index})}.width('100%').height('100%')}}
效果如下图所示

相关文章:
【中工开发者】鸿蒙商城app
这学期我学习了鸿蒙,想用鸿蒙做一个鸿蒙商城app,来展示一下。 项目环境搭建: 1.开发环境:DevEco Studio2.开发语言:ArkTS3.运行环境:Harmony NEXT base1 软件要求: DevEco Studio 5.0.0 Rel…...
(九)机器学习 - 多项式回归
多项式回归(Polynomial Regression)是一种回归分析方法,它将自变量 xx 和因变量 yy 之间的关系建模为 nn 次多项式。多项式回归的目的是找到一个 nn 次多项式函数,使得这个函数能够最好地拟合给定的数据点。 多项式回归的数学表达…...
Qt编写区位码gb2312、机内码、国标码————附带详细介绍和编码实现
文章目录 0 背景1 了解编码1.1 ASCII码1.2 机内码、国标码、区位码1.2.1 区位码1.2.2 国标码(GB 2312-80)1.2.3 汉字机内码(GB 2312) 1.3 GBK和GB2312的区别2 编码实现2.1 QString数据转QByteArray类型2.1.1 使用QTextCodec2.1.2 …...
linux网络编程 | c | epoll实现IO多路转接服务器
epoll实现IO多路转接服务器 可通过以下视频学习 06-opell函数实现的多路IO转接_哔哩哔哩_bilibili 通过响应式–多路IO转接实现 文章目录 epoll实现IO多路转接服务器1.思路&功能核心思路 2.代码实现multi_epoll_sever.c运行图 1.思路&功能 **功能:**客…...
Source Insight的使用经验汇总
01-Add All"和“Add Tree”有何区别? 在 Source Insight 中,“Add All”和“Add Tree”是两种向项目(Project)中添加文件的操作选项,它们的区别在于处理文件和目录的方式不同: 1. Add All 范围&am…...
VSCode 报错:rust-analyzer requires glibc >= 2.28 in latest build
报错信息 /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.953/server/rust-analyzer: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.29 not found (required by /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.9…...
Android Link to Death 使用
Java侧: 【android学习】使用linkToDeath对AIDL双向死亡监听_unlinktodeath-CSDN博客 Native侧: Service端 using namespace android; class MyService :public IBinder::DeathRecipient{void MyService::binderDied(const wp<IBinder>& wh…...
【C++游记】string的使用和模拟实现
枫の个人主页 你不能改变过去,但你可以改变未来 算法/C/数据结构/C Hello,这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕,我们继续来学习C的内容呀。C是接近底层有比较经典的语言,因此学习起来注定枯燥无味…...
DockerUI info存在未授权访问漏洞
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...
SQL,查询每天最接近指定时间的记录
Oracle 数据库的某表有一列是日期时间类型,每天对应多条数据: td1.1.2024 08:08:0811.1.2024 10:10:1021.1.2024 15:15:1531.1.2024 20:20:2042.1.2024 09:09:0952.1.2024 12:12:1262.1.2024 16:16:16712.12.2024 16:16:168 现在要从每天找出两条记录&…...
ElasticSearch如何做性能优化?
大家好,我是锋哥。今天分享关于【ElasticSearch如何做性能优化?】面试题。希望对大家有帮助; ElasticSearch如何做性能优化? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中,性能优化是…...
【Linux】虚拟空间布局模型地址回填数据段合并(万字详解)
Ⅰ、虚拟空间布局模型 理论模型 包括上节的动态库与静态库,加上本节后面两个内容其实都是对gcc的扩展与补充知识,也是需要了解和掌握的知识。在开讲之前,我们先来说一下在32位x86的Linux系统中,虚拟地址空间布局模型:…...
const和修饰指针的几种用法
昨天闲着没事去面试了一个C岗位,问了很多基础的东西都没答上来。主要原因是这些知识在硬件资源丰富的pc端用的不多,二来确实很久没温习之前的C相关的知识了。在面试官问了几次类似的问题没有答好的情况下(还喜欢问你确不确定)&…...
mybatis事务的自动提交与手动提交
MyBatis支持自动提交和手动提交两种事务管理方式。 自动提交事务 MyBatis默认使用自动提交模式,即每个SQL操作都会自动提交到数据库中。这意味着在执行完一条SQL语句后,MyBatis会自动调用commit()方法将更改持久化到数据库。 手动提交事务 可以通过Sq…...
网络安全协议之比较(SSH、PKI、SET、SSL)
一、SSH介绍 什么是SSH? 传统的网络服务程序,如:ftp、pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据, 别有用心的人非常容易就可以截获这些口令和数据。而且,这些服务程序的…...
Vue的生命周期方法
Vue 生命周期方法详解 beforeCreate 执行时机:在实例初始化之后,数据观测(data observer)和事件配置(event/watcher setup)之前被调用。内部状态:此时,组件的选项对象(例…...
ISP和IQ调试(一)
系列文章目录 文章目录 系列文章目录前言一、ISP(image signal process)二、ISP位置三、IQ总结 前言 一、ISP(image signal process) image signal process 图像处理技术 image signal processor 图像信号处理器 设备 什么是图像信号? 代表…...
c# TaskScheduler
这里记录下 TaskScheduler 的简单用法。 使用场景: 使用 Task 的时候,大家知道用 TaskFactory.StartNew 可以用来创建一个 Task 。这里如果创建了 3 个,那么这3个 Task 就各自放飞直接运行了。 class Program {private static TaskFactory…...
可视化数据
数据科学家会直观呈现数据,以更好地理解数据。 他们可以扫描原始数据、检查摘要度量值(如平均值)或绘制数据图表。 图表是一种可视化数据的强有力方式,数据科学家经常使用图表快速了解适度复杂的模式。 直观地表示数据 绘制图表…...
【Redis】Redis缓存击穿
1. 概述 缓存击穿:缓存击穿问题也叫热点key问题,一个高并发的key或重建缓存耗时长(复杂)的key失效了,此时大量的请求给数据库造成巨大的压力。如下图,线程1还在构建缓存时,线程2,3&…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
